@prosekit/extensions 0.16.0-beta.0 → 0.16.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{prosekit-extensions-autocomplete.d.ts → autocomplete.d.ts} +1 -6
- package/dist/autocomplete.d.ts.map +1 -0
- package/dist/{prosekit-extensions-autocomplete.js → autocomplete.js} +1 -9
- package/dist/autocomplete.js.map +1 -0
- package/dist/{prosekit-extensions-background-color.d.ts → background-color.d.ts} +1 -8
- package/dist/background-color.d.ts.map +1 -0
- package/dist/{prosekit-extensions-background-color.js → background-color.js} +1 -7
- package/dist/background-color.js.map +1 -0
- package/dist/{prosekit-extensions-blockquote.d.ts → blockquote.d.ts} +1 -12
- package/dist/blockquote.d.ts.map +1 -0
- package/dist/{prosekit-extensions-blockquote.js → blockquote.js} +2 -12
- package/dist/blockquote.js.map +1 -0
- package/dist/{prosekit-extensions-bold.d.ts → bold.d.ts} +1 -12
- package/dist/bold.d.ts.map +1 -0
- package/dist/{prosekit-extensions-bold.js → bold.js} +2 -12
- package/dist/bold.js.map +1 -0
- package/dist/{prosekit-extensions-code-block.d.ts → code-block.d.ts} +1 -20
- package/dist/code-block.d.ts.map +1 -0
- package/dist/{prosekit-extensions-code-block.js → code-block.js} +3 -21
- package/dist/code-block.js.map +1 -0
- package/dist/{prosekit-extensions-code.d.ts → code.d.ts} +1 -12
- package/dist/code.d.ts.map +1 -0
- package/dist/{prosekit-extensions-code.js → code.js} +2 -12
- package/dist/code.js.map +1 -0
- package/dist/{prosekit-extensions-commit.d.ts → commit.d.ts} +1 -4
- package/dist/commit.d.ts.map +1 -0
- package/dist/{prosekit-extensions-commit.js → commit.js} +1 -3
- package/dist/commit.js.map +1 -0
- package/dist/{prosekit-extensions-doc.d.ts → doc.d.ts} +1 -4
- package/dist/doc.d.ts.map +1 -0
- package/dist/{prosekit-extensions-doc.js → doc.js} +1 -3
- package/dist/doc.js.map +1 -0
- package/dist/{prosekit-extensions-drop-cursor.d.ts → drop-cursor.d.ts} +1 -4
- package/dist/drop-cursor.d.ts.map +1 -0
- package/dist/{prosekit-extensions-drop-cursor.js → drop-cursor.js} +1 -3
- package/dist/drop-cursor.js.map +1 -0
- package/dist/{prosekit-extensions-drop-indicator.d.ts → drop-indicator.d.ts} +1 -4
- package/dist/drop-indicator.d.ts.map +1 -0
- package/dist/drop-indicator.js +2 -57
- package/dist/drop-indicator2.js +53 -0
- package/dist/drop-indicator2.js.map +1 -0
- package/dist/{prosekit-extensions-enter-rule.d.ts → enter-rule.d.ts} +1 -4
- package/dist/enter-rule.d.ts.map +1 -0
- package/dist/{prosekit-extensions-enter-rule.js → enter-rule.js} +1 -3
- package/dist/enter-rule.js.map +1 -0
- package/dist/file.js +2 -128
- package/dist/file2.js +120 -0
- package/dist/file2.js.map +1 -0
- package/dist/{prosekit-extensions-gap-cursor.d.ts → gap-cursor.d.ts} +1 -4
- package/dist/gap-cursor.d.ts.map +1 -0
- package/dist/{prosekit-extensions-gap-cursor.js → gap-cursor.js} +1 -3
- package/dist/gap-cursor.js.map +1 -0
- package/dist/{prosekit-extensions-hard-break.d.ts → hard-break.d.ts} +1 -10
- package/dist/hard-break.d.ts.map +1 -0
- package/dist/{prosekit-extensions-hard-break.js → hard-break.js} +1 -9
- package/dist/hard-break.js.map +1 -0
- package/dist/{prosekit-extensions-heading.d.ts → heading.d.ts} +1 -14
- package/dist/heading.d.ts.map +1 -0
- package/dist/{prosekit-extensions-heading.js → heading.js} +2 -12
- package/dist/heading.js.map +1 -0
- package/dist/{prosekit-extensions-horizontal-rule.d.ts → horizontal-rule.d.ts} +1 -10
- package/dist/horizontal-rule.d.ts.map +1 -0
- package/dist/{prosekit-extensions-horizontal-rule.js → horizontal-rule.js} +2 -10
- package/dist/horizontal-rule.js.map +1 -0
- package/dist/{prosekit-extensions-image.d.ts → image.d.ts} +1 -14
- package/dist/image.d.ts.map +1 -0
- package/dist/{prosekit-extensions-image.js → image.js} +2 -14
- package/dist/image.js.map +1 -0
- package/dist/index.d.ts +0 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/{prosekit-extensions-input-rule.d.ts → input-rule.d.ts} +1 -4
- package/dist/input-rule.d.ts.map +1 -0
- package/dist/{prosekit-extensions-input-rule.js → input-rule.js} +1 -3
- package/dist/input-rule.js.map +1 -0
- package/dist/{prosekit-extensions-italic.d.ts → italic.d.ts} +1 -12
- package/dist/italic.d.ts.map +1 -0
- package/dist/{prosekit-extensions-italic.js → italic.js} +2 -12
- package/dist/italic.js.map +1 -0
- package/dist/{prosekit-extensions-link.d.ts → link.d.ts} +1 -8
- package/dist/link.d.ts.map +1 -0
- package/dist/{prosekit-extensions-link.js → link.js} +5 -11
- package/dist/link.js.map +1 -0
- package/dist/{prosekit-extensions-list.d.ts → list.d.ts} +1 -18
- package/dist/list.d.ts.map +1 -0
- package/dist/{prosekit-extensions-list.js → list.js} +3 -19
- package/dist/list.js.map +1 -0
- package/dist/{prosekit-extensions-loro.d.ts → loro.d.ts} +1 -14
- package/dist/loro.d.ts.map +1 -0
- package/dist/{prosekit-extensions-loro.js → loro.js} +1 -13
- package/dist/loro.js.map +1 -0
- package/dist/{prosekit-extensions-mark-rule.d.ts → mark-rule.d.ts} +1 -6
- package/dist/mark-rule.d.ts.map +1 -0
- package/dist/mark-rule.js +2 -157
- package/dist/mark-rule2.js +151 -0
- package/dist/mark-rule2.js.map +1 -0
- package/dist/{prosekit-extensions-math.d.ts → math.d.ts} +1 -10
- package/dist/math.d.ts.map +1 -0
- package/dist/{prosekit-extensions-math.js → math.js} +3 -11
- package/dist/math.js.map +1 -0
- package/dist/{prosekit-extensions-mention.d.ts → mention.d.ts} +1 -4
- package/dist/mention.d.ts.map +1 -0
- package/dist/{prosekit-extensions-mention.js → mention.js} +1 -3
- package/dist/mention.js.map +1 -0
- package/dist/{prosekit-extensions-mod-click-prevention.d.ts → mod-click-prevention.d.ts} +1 -4
- package/dist/mod-click-prevention.d.ts.map +1 -0
- package/dist/{prosekit-extensions-mod-click-prevention.js → mod-click-prevention.js} +1 -3
- package/dist/mod-click-prevention.js.map +1 -0
- package/dist/{prosekit-extensions-page.d.ts → page.d.ts} +1 -12
- package/dist/page.d.ts.map +1 -0
- package/dist/{prosekit-extensions-page.js → page.js} +3 -15
- package/dist/page.js.map +1 -0
- package/dist/{prosekit-extensions-paragraph.d.ts → paragraph.d.ts} +1 -10
- package/dist/paragraph.d.ts.map +1 -0
- package/dist/{prosekit-extensions-paragraph.js → paragraph.js} +1 -9
- package/dist/paragraph.js.map +1 -0
- package/dist/{prosekit-extensions-paste-rule.d.ts → paste-rule.d.ts} +1 -6
- package/dist/paste-rule.d.ts.map +1 -0
- package/dist/paste-rule.js +2 -158
- package/dist/paste-rule2.js +150 -0
- package/dist/paste-rule2.js.map +1 -0
- package/dist/{prosekit-extensions-placeholder.d.ts → placeholder.d.ts} +1 -4
- package/dist/placeholder.d.ts.map +1 -0
- package/dist/{prosekit-extensions-placeholder.js → placeholder.js} +2 -4
- package/dist/placeholder.js.map +1 -0
- package/dist/{prosekit-extensions-readonly.d.ts → readonly.d.ts} +1 -4
- package/dist/readonly.d.ts.map +1 -0
- package/dist/{prosekit-extensions-readonly.js → readonly.js} +6 -3
- package/dist/readonly.js.map +1 -0
- package/dist/{prosekit-extensions-search.d.ts → search.d.ts} +1 -4
- package/dist/search.d.ts.map +1 -0
- package/dist/{prosekit-extensions-search.js → search.js} +1 -3
- package/dist/search.js.map +1 -0
- package/dist/shiki-highlighter-chunk.js +0 -2
- package/dist/shiki-highlighter-chunk.js.map +1 -1
- package/dist/{prosekit-extensions-strike.d.ts → strike.d.ts} +1 -4
- package/dist/strike.d.ts.map +1 -0
- package/dist/{prosekit-extensions-strike.js → strike.js} +2 -4
- package/dist/strike.js.map +1 -0
- package/dist/{prosekit-extensions-table.d.ts → table.d.ts} +1 -26
- package/dist/table.d.ts.map +1 -0
- package/dist/table.js +2 -276
- package/dist/table2.js +252 -0
- package/dist/table2.js.map +1 -0
- package/dist/{prosekit-extensions-text-align.d.ts → text-align.d.ts} +1 -4
- package/dist/text-align.d.ts.map +1 -0
- package/dist/{prosekit-extensions-text-align.js → text-align.js} +1 -3
- package/dist/text-align.js.map +1 -0
- package/dist/{prosekit-extensions-text-color.d.ts → text-color.d.ts} +1 -8
- package/dist/text-color.d.ts.map +1 -0
- package/dist/{prosekit-extensions-text-color.js → text-color.js} +1 -7
- package/dist/text-color.js.map +1 -0
- package/dist/{prosekit-extensions-text.d.ts → text.d.ts} +1 -4
- package/dist/text.d.ts.map +1 -0
- package/dist/{prosekit-extensions-text.js → text.js} +1 -3
- package/dist/text.js.map +1 -0
- package/dist/{prosekit-extensions-underline.d.ts → underline.d.ts} +1 -4
- package/dist/underline.d.ts.map +1 -0
- package/dist/{prosekit-extensions-underline.js → underline.js} +1 -3
- package/dist/underline.js.map +1 -0
- package/dist/{prosekit-extensions-virtual-selection.d.ts → virtual-selection.d.ts} +1 -4
- package/dist/virtual-selection.d.ts.map +1 -0
- package/dist/{prosekit-extensions-virtual-selection.js → virtual-selection.js} +1 -3
- package/dist/virtual-selection.js.map +1 -0
- package/dist/{prosekit-extensions-yjs.d.ts → yjs.d.ts} +1 -16
- package/dist/yjs.d.ts.map +1 -0
- package/dist/{prosekit-extensions-yjs.js → yjs.js} +1 -13
- package/dist/yjs.js.map +1 -0
- package/package.json +137 -195
- package/src/page/page-element.ts +2 -2
- package/src/readonly/index.ts +6 -0
- package/dist/drop-indicator.js.map +0 -1
- package/dist/file.js.map +0 -1
- package/dist/mark-rule.js.map +0 -1
- package/dist/paste-rule.js.map +0 -1
- package/dist/prosekit-extensions-autocomplete.d.ts.map +0 -1
- package/dist/prosekit-extensions-autocomplete.js.map +0 -1
- package/dist/prosekit-extensions-background-color.d.ts.map +0 -1
- package/dist/prosekit-extensions-background-color.js.map +0 -1
- package/dist/prosekit-extensions-blockquote.d.ts.map +0 -1
- package/dist/prosekit-extensions-blockquote.js.map +0 -1
- package/dist/prosekit-extensions-bold.d.ts.map +0 -1
- package/dist/prosekit-extensions-bold.js.map +0 -1
- package/dist/prosekit-extensions-code-block.d.ts.map +0 -1
- package/dist/prosekit-extensions-code-block.js.map +0 -1
- package/dist/prosekit-extensions-code.d.ts.map +0 -1
- package/dist/prosekit-extensions-code.js.map +0 -1
- package/dist/prosekit-extensions-commit.d.ts.map +0 -1
- package/dist/prosekit-extensions-commit.js.map +0 -1
- package/dist/prosekit-extensions-doc.d.ts.map +0 -1
- package/dist/prosekit-extensions-doc.js.map +0 -1
- package/dist/prosekit-extensions-drop-cursor.d.ts.map +0 -1
- package/dist/prosekit-extensions-drop-cursor.js.map +0 -1
- package/dist/prosekit-extensions-drop-indicator.d.ts.map +0 -1
- package/dist/prosekit-extensions-drop-indicator.js +0 -2
- package/dist/prosekit-extensions-enter-rule.d.ts.map +0 -1
- package/dist/prosekit-extensions-enter-rule.js.map +0 -1
- package/dist/prosekit-extensions-file.js +0 -2
- package/dist/prosekit-extensions-gap-cursor.d.ts.map +0 -1
- package/dist/prosekit-extensions-gap-cursor.js.map +0 -1
- package/dist/prosekit-extensions-hard-break.d.ts.map +0 -1
- package/dist/prosekit-extensions-hard-break.js.map +0 -1
- package/dist/prosekit-extensions-heading.d.ts.map +0 -1
- package/dist/prosekit-extensions-heading.js.map +0 -1
- package/dist/prosekit-extensions-horizontal-rule.d.ts.map +0 -1
- package/dist/prosekit-extensions-horizontal-rule.js.map +0 -1
- package/dist/prosekit-extensions-image.d.ts.map +0 -1
- package/dist/prosekit-extensions-image.js.map +0 -1
- package/dist/prosekit-extensions-input-rule.d.ts.map +0 -1
- package/dist/prosekit-extensions-input-rule.js.map +0 -1
- package/dist/prosekit-extensions-italic.d.ts.map +0 -1
- package/dist/prosekit-extensions-italic.js.map +0 -1
- package/dist/prosekit-extensions-link.d.ts.map +0 -1
- package/dist/prosekit-extensions-link.js.map +0 -1
- package/dist/prosekit-extensions-list.d.ts.map +0 -1
- package/dist/prosekit-extensions-list.js.map +0 -1
- package/dist/prosekit-extensions-loro.d.ts.map +0 -1
- package/dist/prosekit-extensions-loro.js.map +0 -1
- package/dist/prosekit-extensions-mark-rule.d.ts.map +0 -1
- package/dist/prosekit-extensions-mark-rule.js +0 -2
- package/dist/prosekit-extensions-math.d.ts.map +0 -1
- package/dist/prosekit-extensions-math.js.map +0 -1
- package/dist/prosekit-extensions-mention.d.ts.map +0 -1
- package/dist/prosekit-extensions-mention.js.map +0 -1
- package/dist/prosekit-extensions-mod-click-prevention.d.ts.map +0 -1
- package/dist/prosekit-extensions-mod-click-prevention.js.map +0 -1
- package/dist/prosekit-extensions-page.d.ts.map +0 -1
- package/dist/prosekit-extensions-page.js.map +0 -1
- package/dist/prosekit-extensions-paragraph.d.ts.map +0 -1
- package/dist/prosekit-extensions-paragraph.js.map +0 -1
- package/dist/prosekit-extensions-paste-rule.d.ts.map +0 -1
- package/dist/prosekit-extensions-paste-rule.js +0 -2
- package/dist/prosekit-extensions-placeholder.d.ts.map +0 -1
- package/dist/prosekit-extensions-placeholder.js.map +0 -1
- package/dist/prosekit-extensions-readonly.d.ts.map +0 -1
- package/dist/prosekit-extensions-readonly.js.map +0 -1
- package/dist/prosekit-extensions-search.d.ts.map +0 -1
- package/dist/prosekit-extensions-search.js.map +0 -1
- package/dist/prosekit-extensions-strike.d.ts.map +0 -1
- package/dist/prosekit-extensions-strike.js.map +0 -1
- package/dist/prosekit-extensions-table.d.ts.map +0 -1
- package/dist/prosekit-extensions-table.js +0 -2
- package/dist/prosekit-extensions-text-align.d.ts.map +0 -1
- package/dist/prosekit-extensions-text-align.js.map +0 -1
- package/dist/prosekit-extensions-text-color.d.ts.map +0 -1
- package/dist/prosekit-extensions-text-color.js.map +0 -1
- package/dist/prosekit-extensions-text.d.ts.map +0 -1
- package/dist/prosekit-extensions-text.js.map +0 -1
- package/dist/prosekit-extensions-underline.d.ts.map +0 -1
- package/dist/prosekit-extensions-underline.js.map +0 -1
- package/dist/prosekit-extensions-virtual-selection.d.ts.map +0 -1
- package/dist/prosekit-extensions-virtual-selection.js.map +0 -1
- package/dist/prosekit-extensions-yjs.d.ts.map +0 -1
- package/dist/prosekit-extensions-yjs.js.map +0 -1
- package/dist/table.js.map +0 -1
- /package/dist/{prosekit-extensions-file.d.ts → file.d.ts} +0 -0
- /package/dist/{prosekit-extensions.js → index.js} +0 -0
- /package/dist/{prosekit-extensions.d.ts → index2.d.ts} +0 -0
package/src/page/page-element.ts
CHANGED
|
@@ -9,10 +9,10 @@ export const PAGE_CHUNK_TAG_NAME = 'pm-page-chunk'
|
|
|
9
9
|
/**
|
|
10
10
|
* @internal
|
|
11
11
|
*/
|
|
12
|
-
export
|
|
12
|
+
export function registerPageChunkElement(): void {
|
|
13
13
|
if (typeof window === 'undefined' || customElements.get(PAGE_CHUNK_TAG_NAME)) return
|
|
14
14
|
customElements.define(PAGE_CHUNK_TAG_NAME, PageChunkElement)
|
|
15
|
-
}
|
|
15
|
+
}
|
|
16
16
|
|
|
17
17
|
class PageChunkElement extends HTMLElement {
|
|
18
18
|
static observedAttributes = [
|
package/src/readonly/index.ts
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"drop-indicator.js","names":[],"sources":["../src/drop-indicator/drop-indicator-facet.ts","../src/drop-indicator/drop-indicator.ts"],"sourcesContent":["import { isNotNullish } from '@ocavue/utils'\nimport { defineFacet, defineFacetPayload, pluginFacet, type PlainExtension, type PluginPayload } from '@prosekit/core'\nimport type { DragEventHandler, DropIndicatorPluginOptions, ShowHandler } 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 const showHandlers = payloads.map(p => p.onShow).filter(isNotNullish)\n const hideHandlers = payloads.map(p => p.onHide).filter(isNotNullish)\n const dragHandlers = payloads.map(p => p.onDrag).filter(isNotNullish)\n\n const showHandler: ShowHandler = (options) => {\n for (const fn of showHandlers) {\n fn(options)\n }\n }\n\n const hideHandler: VoidFunction = () => {\n for (const fn of hideHandlers) {\n fn()\n }\n }\n\n const dragHandler: DragEventHandler = (options): boolean => {\n for (const 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.ts'\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":";;;;;;;AAQA,SAAgB,2BACd,SACgB;AAChB,QAAO,mBAAmB,oBAAoB,CAAC,QAAQ,CAAC;;AAG1D,MAAM,qBAAqB,YAAuD;CAChF,QAAQ;CACR,WAAW;CACX,UAAU,aAA0D;EAClE,MAAM,eAAe,SAAS,KAAI,MAAK,EAAE,OAAO,CAAC,OAAO,aAAa;EACrE,MAAM,eAAe,SAAS,KAAI,MAAK,EAAE,OAAO,CAAC,OAAO,aAAa;EACrE,MAAM,eAAe,SAAS,KAAI,MAAK,EAAE,OAAO,CAAC,OAAO,aAAa;EAErE,MAAM,eAA4B,YAAY;AAC5C,QAAK,MAAM,MAAM,aACf,IAAG,QAAQ;;EAIf,MAAM,oBAAkC;AACtC,QAAK,MAAM,MAAM,aACf,KAAI;;EAIR,MAAM,eAAiC,YAAqB;AAC1D,QAAK,MAAM,MAAM,aACf,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;;;;;;;;;;;;;;;;AC7BF,SAAgB,oBACd,SACwB;AACxB,QAAO,2BAA2B,WAAW,EAAE,CAAC"}
|
package/dist/file.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"file.js","names":["facet","getFiles"],"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.ts'\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.ts'\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,UACS;CACT,MAAM,QAAQ,SAAS,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,mBAAmBA,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,MAAM,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,EACpEC,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,MAAM,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,kBACE,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"}
|
package/dist/mark-rule.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"mark-rule.js","names":[],"sources":["../src/mark-rule/range.ts","../src/mark-rule/apply.ts","../src/mark-rule/mark-rule.ts"],"sourcesContent":["import type { ProseMirrorNode, ResolvedPos } from '@prosekit/pm/model'\nimport type { EditorState, Transaction } 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 { getMarkType, maybeRun, OBJECT_REPLACEMENT_CHARACTER } from '@prosekit/core'\nimport type { Mark, ProseMirrorNode } from '@prosekit/pm/model'\nimport type { EditorState, Transaction } from '@prosekit/pm/state'\n\nimport { getCheckRanges } from './range.ts'\nimport type { MarkRuleOptions } from './types.ts'\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 { defineFacet, defineFacetPayload, pluginFacet, type PlainExtension, type PluginPayload } from '@prosekit/core'\nimport { PluginKey, ProseMirrorPlugin, type EditorState, type Transaction } from '@prosekit/pm/state'\n\nimport { applyMarkRules } from './apply.ts'\nimport type { MarkRuleOptions } from './types.ts'\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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"}
|
package/dist/paste-rule.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"paste-rule.js","names":[],"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 { defineFacet, defineFacetPayload, pluginFacet, type PlainExtension, type PluginPayload } from '@prosekit/core'\nimport type { Slice } from '@prosekit/pm/model'\nimport { PluginKey, ProseMirrorPlugin } 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.ts'\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 { getMarkType, type PlainExtension } from '@prosekit/core'\nimport type { Attrs, MarkType, ProseMirrorNode } from '@prosekit/pm/model'\nimport { Fragment, Slice } from '@prosekit/pm/model'\n\nimport { definePasteRule } from './paste-rule.ts'\nimport { splitTextByRegex } from './split-text-by-regex.ts'\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 const 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 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"prosekit-extensions-autocomplete.d.ts","names":[],"sources":["../src/autocomplete/autocomplete-rule.ts","../src/autocomplete/autocomplete.ts"],"mappings":";;;;;;;UAOiB,mBAAA;EAAmB;;;EAIlC,KAAA,EAAO,WAAA;EAAA;;;EAKP,KAAA,EAAO,eAAA;EAUP;;;EALA,IAAA;EAkBW;AAOb;;EApBE,EAAA;EAoBmC;;AAKrC;;EAnBE,WAAA;EAuBA;;AAMF;;;EAtBE,WAAA;AAAA;AA2BF;;;;AAAA,KApBY,YAAA,IAAgB,OAAA,EAAS,mBAAA;;;;UAKpB,eAAA;EAuBf;;;EAnBA,KAAA,EAAO,WAAA;AAAA;;;;KAMG,iBAAA,IAAqB,OAAA,EAAS,eAAA;;AAuC1C;;UAlCiB,uBAAA;EAoCC;;;;;;;EA5BhB,KAAA,EAAO,MAAA;EA4BS;;;;EAtBhB,OAAA,EAAS,YAAA;EA4BA;;;EAvBT,OAAA,GAAU,YAAA;;;;;;EAOV,QAAA,GAAW,iBAAA;AAAA;;AC/Eb;;;;cDuFa,gBAAA;ECvFsB;EAAA,SDyFxB,KAAA,EAAO,MAAA;ECzFmD;EAAA,SD2F1D,OAAA,EAAS,YAAA;;WAET,OAAA,GAAU,YAAA;;WAEV,QAAA,GAAW,OAAA;IAAW,KAAA,EAAO,WAAA;EAAA;cAE1B,OAAA,EAAS,uBAAA;AAAA;;;;;AAvGvB;;;;;;iBCMgB,kBAAA,CAAmB,IAAA,EAAM,gBAAA,GAAmB,SAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"prosekit-extensions-autocomplete.js","names":[],"sources":["../src/autocomplete/autocomplete-helpers.ts","../src/autocomplete/autocomplete-rule.ts","../src/autocomplete/autocomplete-plugin.ts","../src/autocomplete/autocomplete.ts"],"sourcesContent":["import type { ResolvedPos } from '@prosekit/pm/model'\nimport { PluginKey, type EditorState, type Transaction } from '@prosekit/pm/state'\n\nimport type { AutocompleteRule } from './autocomplete-rule.ts'\n\nexport function defaultCanMatch({ state }: { state: EditorState }): boolean {\n const $pos = state.selection.$from\n return !isInsideCodeBlock($pos) && !isInsideCodeMark($pos)\n}\n\nfunction isInsideCodeBlock($pos: ResolvedPos): boolean {\n for (let d = $pos.depth; d > 0; d--) {\n if ($pos.node(d).type.spec.code) {\n return true\n }\n }\n return false\n}\n\nfunction isInsideCodeMark($pos: ResolvedPos): boolean {\n for (const mark of $pos.marks()) {\n if (mark.type.spec.code) {\n return true\n }\n }\n return false\n}\n\n/**\n * @internal\n */\nexport interface PredictionPluginMatching {\n rule: AutocompleteRule\n from: number\n to: number\n match: RegExpExecArray\n}\n\n/**\n * @internal\n */\nexport interface PredictionPluginState {\n /**\n * The matching positions that should be ignored.\n */\n ignores: Array<number>\n\n /**\n * The current active matching.\n */\n matching: PredictionPluginMatching | null\n}\n\n/**\n * @internal\n */\nexport type PredictionTransactionMeta = {\n type: 'enter'\n matching: PredictionPluginMatching\n} | {\n type: 'leave'\n}\n\nexport function getPluginState(state: EditorState): PredictionPluginState | undefined {\n return pluginKey.getState(state)\n}\n\nexport function getTrMeta(tr: Transaction): PredictionTransactionMeta | undefined {\n return tr.getMeta(pluginKey) as PredictionTransactionMeta | undefined\n}\n\nexport function setTrMeta(\n tr: Transaction,\n meta: PredictionTransactionMeta,\n): Transaction {\n return tr.setMeta(pluginKey, meta)\n}\n\nexport const pluginKey: PluginKey<PredictionPluginState> = new PluginKey<PredictionPluginState>('prosekit-autocomplete')\n","import type { EditorState } from '@prosekit/pm/state'\n\nimport { defaultCanMatch } from './autocomplete-helpers.ts'\n\n/**\n * Options for the {@link MatchHandler} callback.\n */\nexport interface MatchHandlerOptions {\n /**\n * The editor state.\n */\n state: EditorState\n\n /**\n * The result of `RegExp.exec`.\n */\n match: RegExpExecArray\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 * Call this function to ignore the match. You probably want to call this\n * function when the user presses the `Escape` key.\n */\n ignoreMatch: () => void\n\n /**\n * Call this function to delete the matched text. For example, in a slash\n * menu, you might want to delete the matched text first then do something\n * else when the user presses the `Enter` key.\n */\n deleteMatch: () => void\n}\n\n/**\n * A callback that is called when the rule starts to match, and also on\n * subsequent updates while the rule continues to match.\n */\nexport type MatchHandler = (options: MatchHandlerOptions) => void\n\n/**\n * Options for the {@link CanMatchPredicate} callback.\n */\nexport interface CanMatchOptions {\n /**\n * The editor state.\n */\n state: EditorState\n}\n\n/**\n * A predicate to determine if the rule can be applied in the current editor state.\n */\nexport type CanMatchPredicate = (options: CanMatchOptions) => boolean\n\n/**\n * Options for creating an {@link AutocompleteRule}\n */\nexport interface AutocompleteRuleOptions {\n /**\n * The regular expression to match against the text before the cursor. The\n * last match before the cursor is used.\n *\n * For a slash menu, you might use `/(?<!\\S)\\/(\\S.*)?$/u`.\n * For a mention, you might use `/@\\w*$/`\n */\n regex: RegExp\n\n /**\n * A callback that is called when the rule starts to match, and also on\n * subsequent updates while the rule continues to match.\n */\n onEnter: MatchHandler\n\n /**\n * A callback that is called when the rule stops matching.\n */\n onLeave?: VoidFunction\n\n /**\n * A predicate to determine if the rule can be applied in the current editor\n * state. If not provided, it defaults to only allowing matches that are not\n * inside a code block or code mark.\n */\n canMatch?: CanMatchPredicate\n}\n\n/**\n * An autocomplete rule that can be used to create an autocomplete extension.\n *\n * @public\n */\nexport class AutocompleteRule {\n /** @internal */\n readonly regex: RegExp\n /** @internal */\n readonly onMatch: MatchHandler\n /** @internal */\n readonly onLeave?: VoidFunction\n /** @internal */\n readonly canMatch: (options: { state: EditorState }) => boolean\n\n constructor(options: AutocompleteRuleOptions) {\n this.regex = options.regex\n this.onMatch = options.onEnter\n this.onLeave = options.onLeave\n this.canMatch = options.canMatch ?? defaultCanMatch\n }\n}\n","import { OBJECT_REPLACEMENT_CHARACTER } from '@prosekit/core'\nimport type { ProseMirrorNode, ResolvedPos } from '@prosekit/pm/model'\nimport { Plugin, type EditorState, type Transaction } from '@prosekit/pm/state'\nimport type { Mapping } from '@prosekit/pm/transform'\nimport type { EditorView } from '@prosekit/pm/view'\nimport { Decoration, DecorationSet } from '@prosekit/pm/view'\n\nimport {\n getPluginState,\n getTrMeta,\n pluginKey,\n setTrMeta,\n type PredictionPluginMatching,\n type PredictionPluginState,\n type PredictionTransactionMeta,\n} from './autocomplete-helpers.ts'\nimport type { AutocompleteRule } from './autocomplete-rule.ts'\n\n/**\n * Creates a plugin that handles autocomplete functionality.\n *\n * Workflow:\n *\n * 1. {@link handleTextInput}: called when text is going to be input, but the\n * transaction is not yet created. Injects a new matching as a transaction\n * meta if applicable. This is the only place to create a new matching if\n * there is no existing matching.\n * 2. {@link handleTransaction}: called when a transaction is going to be\n * applied. Updates the plugin state based on the transaction. This step\n * determines if a matching should be created, updated or removed.\n * 3. {@link handleUpdate}: called when the editor state is updated. This is the\n * place to call `onMatch` and register `deleteMatch` and `ignoreMatch`\n * callbacks.\n * 4. {@link getDecorations}: creates the decorations for the current matching.\n */\nexport function createAutocompletePlugin({\n getRules,\n}: {\n getRules: () => AutocompleteRule[]\n}): Plugin {\n return new Plugin<PredictionPluginState>({\n key: pluginKey,\n\n state: {\n init: (): PredictionPluginState => {\n return { ignores: [], matching: null }\n },\n apply: (tr, prevValue, oldState, newState): PredictionPluginState => {\n return handleTransaction(tr, prevValue, oldState, newState, getRules)\n },\n },\n\n view: () => ({\n update: handleUpdate,\n }),\n\n props: {\n handleTextInput: (view, from, to, textAdded, getTr) => {\n const meta = handleTextInput(view, from, to, textAdded, getRules)\n if (meta) {\n const tr = getTr()\n setTrMeta(tr, meta)\n view.dispatch(tr)\n return true\n }\n return false\n },\n decorations: getDecorations,\n },\n })\n}\n\nfunction handleTextInput(\n view: EditorView,\n from: number,\n to: number,\n textAdded: string,\n getRules: () => AutocompleteRule[],\n): PredictionTransactionMeta | undefined {\n // Only handle insertions\n if (from !== to) {\n return\n }\n\n const textBackward = getTextBackward(view.state.doc.resolve(from))\n const textFull = textBackward + textAdded\n const textTo = to + textAdded.length\n const textFrom = textTo - textFull.length\n\n const pluginState = getPluginState(view.state)\n const ignores = pluginState?.ignores ?? []\n\n const currMatching = matchRule(\n view.state,\n getRules(),\n textFull,\n textFrom,\n textTo,\n ignores,\n )\n\n if (currMatching) {\n return { type: 'enter', matching: currMatching }\n }\n}\n\nfunction handleTransaction(\n tr: Transaction,\n prevValue: PredictionPluginState,\n oldState: EditorState,\n newState: EditorState,\n getRules: () => AutocompleteRule[],\n): PredictionPluginState {\n const meta = getTrMeta(tr)\n\n if (\n !meta\n && !tr.docChanged\n && oldState.selection.eq(newState.selection)\n ) {\n // No changes\n return prevValue\n }\n\n // Handle position mapping changes\n const ignoreSet = new Set<number>()\n for (const ignore of prevValue.ignores) {\n const result = tr.mapping.mapResult(ignore)\n if (!result.deletedBefore && !result.deletedAfter) {\n ignoreSet.add(result.pos)\n }\n }\n const ignores = Array.from(ignoreSet)\n\n const prevMatching = prevValue.matching && mapMatching(prevValue.matching, tr.mapping)\n\n // If there is no new matching from `handleTextInput`\n if (!meta) {\n if (!prevMatching) {\n return { matching: null, ignores }\n }\n\n const { selection } = newState\n // If the text selection is before the matching or after the matching,\n // we leave the matching\n if (selection.to < prevMatching.from || selection.from > prevMatching.to) {\n ignores.push(prevMatching.from)\n return { matching: null, ignores }\n }\n\n // Get the text between the existing matching\n const text = getTextBetween(newState.doc, prevMatching.from, prevMatching.to)\n // Check the text again to see if it still matches the rule\n const currMatching = matchRule(\n newState,\n getRules(),\n text,\n prevMatching.from,\n prevMatching.to,\n ignores,\n )\n return { matching: currMatching ?? null, ignores }\n }\n\n // If a new matching is being entered from `handleTextInput`\n if (meta.type === 'enter') {\n // Ignore the previous matching if it is not the same as the new matching\n if (prevMatching && prevMatching.from !== meta.matching.from) {\n ignores.push(prevMatching.from)\n }\n\n // Return the new matching\n return { matching: meta.matching, ignores }\n }\n\n // If a matching is being exited\n if (meta.type === 'leave') {\n if (prevMatching) {\n ignores.push(prevMatching.from)\n }\n return { matching: null, ignores }\n }\n\n throw new Error(`Invalid transaction meta: ${meta satisfies never}`)\n}\n\nfunction handleUpdate(view: EditorView, prevState: EditorState): void {\n const prevValue = getPluginState(prevState)\n const currValue = getPluginState(view.state)\n\n if (!prevValue || !currValue) {\n // Should not happen\n return\n }\n\n const prevMatching = prevValue.matching\n const currMatching = currValue.matching\n\n // Deactivate the previous rule\n if (prevMatching && prevMatching.rule !== currMatching?.rule) {\n prevMatching.rule.onLeave?.()\n }\n\n // Activate the current rule\n if (currMatching) {\n const { from, to, match, rule } = currMatching\n\n const textSnapshot = getTextBetween(view.state.doc, from, to)\n\n const deleteMatch = () => {\n if (getTextBetween(view.state.doc, from, to) === textSnapshot) {\n view.dispatch(view.state.tr.delete(from, to))\n }\n }\n\n const ignoreMatch = () => {\n view.dispatch(\n setTrMeta(view.state.tr, { type: 'leave' }),\n )\n }\n\n rule.onMatch({\n state: view.state,\n match,\n from,\n to,\n deleteMatch,\n ignoreMatch,\n })\n }\n}\n\nfunction getDecorations(state: EditorState): DecorationSet | null {\n const pluginState = getPluginState(state)\n if (pluginState?.matching) {\n const { from, to, match } = pluginState.matching\n const deco = Decoration.inline(from, to, {\n 'class': 'prosekit-autocomplete-match',\n 'data-autocomplete-match-text': match[0],\n })\n return DecorationSet.create(state.doc, [deco])\n }\n return null\n}\n\nconst MAX_MATCH = 200\n\n/** Get the text before the given position at the current block. */\nfunction getTextBackward($pos: ResolvedPos): string {\n const parentOffset: number = $pos.parentOffset\n return getTextBetween(\n $pos.parent,\n Math.max(0, parentOffset - MAX_MATCH),\n parentOffset,\n )\n}\n\nfunction getTextBetween(node: ProseMirrorNode, from: number, to: number): string {\n return node.textBetween(\n from,\n to,\n null,\n OBJECT_REPLACEMENT_CHARACTER,\n )\n}\n\nfunction matchRule(\n state: EditorState,\n rules: AutocompleteRule[],\n text: string,\n textFrom: number,\n textTo: number,\n ignores: Array<number>,\n): PredictionPluginMatching | undefined {\n // Find the rightmost ignore point within the text range\n let maxIgnore = -1\n for (const ignore of ignores) {\n if (ignore >= textFrom && ignore < textTo && ignore > maxIgnore) {\n maxIgnore = ignore\n }\n }\n\n // If an ignore point is within the text range, we ignore the text to the left\n // of the ignore point (including the character right after the ignore point).\n if (maxIgnore >= 0) {\n const cut = maxIgnore + 1 - textFrom\n text = text.slice(cut)\n textFrom += cut\n }\n\n if (textFrom >= textTo || !text) {\n return\n }\n\n for (const rule of rules) {\n if (!rule.canMatch({ state })) {\n continue\n }\n\n rule.regex.lastIndex = 0\n const match = rule.regex.exec(text)\n if (!match) {\n continue\n }\n\n const matchTo = textTo\n const matchFrom = textFrom + match.index\n\n return { rule, match, from: matchFrom, to: matchTo }\n }\n}\n\nfunction mapMatching(matching: PredictionPluginMatching, mapping: Mapping): PredictionPluginMatching {\n return {\n rule: matching.rule,\n match: matching.match,\n from: mapping.map(matching.from),\n to: mapping.map(matching.to, -1),\n }\n}\n","import { defineFacet, defineFacetPayload, pluginFacet, type Extension, type PluginPayload } from '@prosekit/core'\n\nimport { createAutocompletePlugin } from './autocomplete-plugin.ts'\nimport type { AutocompleteRule } from './autocomplete-rule.ts'\n\n/**\n * Defines an autocomplete extension that executes logic when the text before\n * the cursor matches the given regular expression.\n *\n * When a match is found, an inline decoration is applied to the matched text\n * with the class `prosekit-autocomplete-match` and a `data-autocomplete-match-text`\n * attribute containing the full matched string.\n */\nexport function defineAutocomplete(rule: AutocompleteRule): Extension {\n return defineFacetPayload(autocompleteFacet, [rule])\n}\n\nconst autocompleteFacet = defineFacet<AutocompleteRule, PluginPayload>({\n reduce: () => {\n let rules: AutocompleteRule[] = []\n const getRules = () => rules\n const plugin = createAutocompletePlugin({ getRules })\n\n return function reducer(inputs) {\n rules = inputs\n return plugin\n }\n },\n parent: pluginFacet,\n singleton: true,\n})\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"prosekit-extensions-background-color.d.ts","names":[],"sources":["../src/background-color/background-color-spec.ts","../src/background-color/background-color-commands.ts","../src/background-color/background-color.ts"],"mappings":";;;;;;;AAOA;;UAAiB,oBAAA;EACf,KAAA;AAAA;AAMF;;;AAAA,KAAY,4BAAA,GAA+B,SAAA;EACzC,KAAA;IACE,eAAA,EAAiB,oBAAA;EAAA;AAAA;;;AAOrB;iBAAgB,yBAAA,CAAA,GAA6B,4BAAA;;;;AAhB7C;;iBCCgB,kBAAA,CAAmB,KAAA,EAAO,oBAAA,GAAuB,OAAA;;;ADMjE;iBCCgB,qBAAA,CAAA,GAAyB,OAAA;;;;KAO7B,gCAAA,GAAmC,SAAA;EAC7C,QAAA;IACE,kBAAA,GAAqB,KAAA,EAAO,oBAAA;IAC5B,qBAAA;EAAA;AAAA;;;;iBAOY,6BAAA,CAAA,GAAiC,gCAAA;;;;ADzBjD;;KECY,wBAAA,GAA2B,KAAA,EAAO,4BAAA,EAA8B,gCAAA;;;AFM5E;;;iBECgB,qBAAA,CAAA,GAAyB,wBAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"prosekit-extensions-background-color.js","names":[],"sources":["../src/background-color/background-color-commands.ts","../src/background-color/background-color-spec.ts","../src/background-color/background-color.ts"],"sourcesContent":["import { addMark, defineCommands, removeMark, type Extension } from '@prosekit/core'\nimport type { Command } from '@prosekit/pm/state'\n\nimport type { BackgroundColorAttrs } from './background-color-spec.ts'\n\n/**\n * @internal\n */\nexport function addBackgroundColor(attrs: BackgroundColorAttrs): Command {\n return addMark({ type: 'backgroundColor', attrs })\n}\n\n/**\n * @internal\n */\nexport function removeBackgroundColor(): Command {\n return removeMark({ type: 'backgroundColor' })\n}\n\n/**\n * @internal\n */\nexport type BackgroundColorCommandsExtension = Extension<{\n Commands: {\n addBackgroundColor: [attrs: BackgroundColorAttrs]\n removeBackgroundColor: []\n }\n}>\n\n/**\n * @internal\n */\nexport function defineBackgroundColorCommands(): BackgroundColorCommandsExtension {\n return defineCommands({ addBackgroundColor, removeBackgroundColor })\n}\n","import { defineMarkSpec, type Extension } from '@prosekit/core'\n\n/**\n * Attributes for the `backgroundColor` mark.\n *\n * @public\n */\nexport interface BackgroundColorAttrs {\n color: string\n}\n\n/**\n * @internal\n */\nexport type BackgroundColorSpecExtension = Extension<{\n Marks: {\n backgroundColor: BackgroundColorAttrs\n }\n}>\n\n/**\n * @internal\n */\nexport function defineBackgroundColorSpec(): BackgroundColorSpecExtension {\n return defineMarkSpec<'backgroundColor', BackgroundColorAttrs>({\n name: 'backgroundColor',\n attrs: {\n color: {\n validate: 'string',\n },\n },\n parseDOM: [\n {\n tag: ':where([style*=\"background-color:\"], [data-background-color])',\n getAttrs: (node): BackgroundColorAttrs | false => {\n // When both `data-background-color` and `style=\"background-color\"` are present, we\n // prioritize the `data-background-color` attribute. This avoids the\n // browser's default behavior of changing hex colors to rgba in style\n // attribute.\n const value = node.getAttribute('data-background-color')\n if (value && value !== 'inherit') {\n return { color: value }\n }\n const color = node.style.backgroundColor\n if (color && color !== 'inherit') {\n return { color }\n }\n return false\n },\n consuming: false,\n },\n ],\n toDOM(mark) {\n const color = (mark.attrs as BackgroundColorAttrs).color\n return ['span', { 'style': `background-color: ${color};`, 'data-background-color': color }, 0]\n },\n })\n}\n","import { union, type Union } from '@prosekit/core'\n\nimport { defineBackgroundColorCommands, type BackgroundColorCommandsExtension } from './background-color-commands.ts'\nimport { defineBackgroundColorSpec, type BackgroundColorSpecExtension } from './background-color-spec.ts'\n\n/**\n * @internal\n */\nexport type BackgroundColorExtension = Union<[BackgroundColorSpecExtension, BackgroundColorCommandsExtension]>\n\n/**\n * Defines the `backgroundColor` mark and some commands for it.\n *\n * @public\n */\nexport function defineBackgroundColor(): BackgroundColorExtension {\n return union(\n defineBackgroundColorSpec(),\n defineBackgroundColorCommands(),\n )\n}\n"],"mappings":";;;;;AAQA,SAAgB,mBAAmB,OAAsC;AACvE,QAAO,QAAQ;EAAE,MAAM;EAAmB;EAAO,CAAC;;;;;AAMpD,SAAgB,wBAAiC;AAC/C,QAAO,WAAW,EAAE,MAAM,mBAAmB,CAAC;;;;;AAgBhD,SAAgB,gCAAkE;AAChF,QAAO,eAAe;EAAE;EAAoB;EAAuB,CAAC;;;;;;;ACVtE,SAAgB,4BAA0D;AACxE,QAAO,eAAwD;EAC7D,MAAM;EACN,OAAO,EACL,OAAO,EACL,UAAU,UACX,EACF;EACD,UAAU,CACR;GACE,KAAK;GACL,WAAW,SAAuC;IAKhD,MAAM,QAAQ,KAAK,aAAa,wBAAwB;AACxD,QAAI,SAAS,UAAU,UACrB,QAAO,EAAE,OAAO,OAAO;IAEzB,MAAM,QAAQ,KAAK,MAAM;AACzB,QAAI,SAAS,UAAU,UACrB,QAAO,EAAE,OAAO;AAElB,WAAO;;GAET,WAAW;GACZ,CACF;EACD,MAAM,MAAM;GACV,MAAM,QAAS,KAAK,MAA+B;AACnD,UAAO;IAAC;IAAQ;KAAE,SAAS,qBAAqB,MAAM;KAAI,yBAAyB;KAAO;IAAE;IAAE;;EAEjG,CAAC;;;;;;;;;ACzCJ,SAAgB,wBAAkD;AAChE,QAAO,MACL,2BAA2B,EAC3B,+BAA+B,CAChC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"prosekit-extensions-blockquote.d.ts","names":[],"sources":["../src/blockquote/blockquote-commands.ts","../src/blockquote/blockquote-input-rule.ts","../src/blockquote/blockquote-keymap.ts","../src/blockquote/blockquote-spec.ts","../src/blockquote/blockquote.ts"],"mappings":";;;;KAEY,2BAAA,GAA8B,SAAA;EACxC,QAAA;IACE,aAAA;IACA,gBAAA;IACA,gBAAA;EAAA;AAAA;;;;iBAOY,wBAAA,CAAA,GAA4B,2BAAA;;;;;;AAX5C;iBCMgB,yBAAA,CAAA,GAA6B,cAAA;;;;;;iBCc7B,sBAAA,CAAA,GAA0B,cAAA;;;KCnB9B,uBAAA,GAA0B,SAAA;EACpC,KAAA;IACE,UAAA,EAAY,KAAA;EAAA;AAAA;AAAA,iBAIA,oBAAA,CAAA,GAAwB,uBAAA;;;;AHPxC;;KIQY,mBAAA,GAAsB,KAAA,EAC/B,uBAAA,EAAyB,2BAAA;;;;iBAMZ,gBAAA,CAAA,GAAoB,mBAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"prosekit-extensions-blockquote.js","names":[],"sources":["../src/blockquote/blockquote-commands.ts","../src/blockquote/blockquote-input-rule.ts","../src/blockquote/blockquote-keymap.ts","../src/blockquote/blockquote-spec.ts","../src/blockquote/blockquote.ts"],"sourcesContent":["import { defineCommands, insertNode, toggleWrap, wrap, type Extension } from '@prosekit/core'\n\nexport type BlockquoteCommandsExtension = Extension<{\n Commands: {\n setBlockquote: []\n insertBlockquote: []\n toggleBlockquote: []\n }\n}>\n\n/**\n * @internal\n */\nexport function defineBlockquoteCommands(): BlockquoteCommandsExtension {\n return defineCommands({\n setBlockquote: () => {\n return wrap({ type: 'blockquote' })\n },\n insertBlockquote: () => {\n return insertNode({ type: 'blockquote' })\n },\n toggleBlockquote: () => {\n return toggleWrap({ type: 'blockquote' })\n },\n })\n}\n","import type { PlainExtension } from '@prosekit/core'\n\nimport { defineWrappingInputRule } from '../input-rule/index.ts'\n\n/**\n * Wraps the text block in a blockquote when `>` is typed at the start of a new\n * line followed by a space.\n */\nexport function defineBlockquoteInputRule(): PlainExtension {\n return defineWrappingInputRule({\n regex: /^>\\s/,\n type: 'blockquote',\n })\n}\n","import { defineKeymap, isAtBlockStart, toggleWrap, type PlainExtension } from '@prosekit/core'\nimport { joinBackward } from '@prosekit/pm/commands'\nimport type { Command } from '@prosekit/pm/state'\n\nfunction toggleBlockquoteKeybinding(): Command {\n return toggleWrap({ type: 'blockquote' })\n}\n\nconst backspaceUnsetBlockquoteCommand: Command = (state, dispatch, view): boolean => {\n const $pos = isAtBlockStart(state, view)\n if ($pos?.node(-1).type.name === 'blockquote') {\n return joinBackward(state, dispatch, view)\n }\n return false\n}\n\nfunction backspaceUnsetBlockquote(): Command {\n return backspaceUnsetBlockquoteCommand\n}\n/**\n * @internal\n */\nexport function defineBlockquoteKeymap(): PlainExtension {\n return defineKeymap({\n 'Mod-B': toggleBlockquoteKeybinding(),\n 'Backspace': backspaceUnsetBlockquote(),\n })\n}\n","import { defineNodeSpec, type Extension } from '@prosekit/core'\nimport type { Attrs } from '@prosekit/pm/model'\n\nexport type BlockquoteSpecExtension = Extension<{\n Nodes: {\n blockquote: Attrs\n }\n}>\n\nexport function defineBlockquoteSpec(): BlockquoteSpecExtension {\n return defineNodeSpec({\n name: 'blockquote',\n content: 'block+',\n group: 'block',\n defining: true,\n parseDOM: [{ tag: 'blockquote' }],\n toDOM() {\n return ['blockquote', 0]\n },\n })\n}\n","import { union, type Union } from '@prosekit/core'\n\nimport { defineBlockquoteCommands, type BlockquoteCommandsExtension } from './blockquote-commands.ts'\nimport { defineBlockquoteInputRule } from './blockquote-input-rule.ts'\nimport { defineBlockquoteKeymap } from './blockquote-keymap.ts'\nimport { defineBlockquoteSpec, type BlockquoteSpecExtension } from './blockquote-spec.ts'\n\n/**\n * @internal\n */\nexport type BlockquoteExtension = Union<\n [BlockquoteSpecExtension, BlockquoteCommandsExtension]\n>\n\n/**\n * @public\n */\nexport function defineBlockquote(): BlockquoteExtension {\n return union(\n defineBlockquoteSpec(),\n defineBlockquoteInputRule(),\n defineBlockquoteCommands(),\n defineBlockquoteKeymap(),\n )\n}\n"],"mappings":";;;;;;;AAaA,SAAgB,2BAAwD;AACtE,QAAO,eAAe;EACpB,qBAAqB;AACnB,UAAO,KAAK,EAAE,MAAM,cAAc,CAAC;;EAErC,wBAAwB;AACtB,UAAO,WAAW,EAAE,MAAM,cAAc,CAAC;;EAE3C,wBAAwB;AACtB,UAAO,WAAW,EAAE,MAAM,cAAc,CAAC;;EAE5C,CAAC;;;;;;;;AChBJ,SAAgB,4BAA4C;AAC1D,QAAO,wBAAwB;EAC7B,OAAO;EACP,MAAM;EACP,CAAC;;;;ACRJ,SAAS,6BAAsC;AAC7C,QAAO,WAAW,EAAE,MAAM,cAAc,CAAC;;AAG3C,MAAM,mCAA4C,OAAO,UAAU,SAAkB;AAEnF,KADa,eAAe,OAAO,KAAK,EAC9B,KAAK,GAAG,CAAC,KAAK,SAAS,aAC/B,QAAO,aAAa,OAAO,UAAU,KAAK;AAE5C,QAAO;;AAGT,SAAS,2BAAoC;AAC3C,QAAO;;;;;AAKT,SAAgB,yBAAyC;AACvD,QAAO,aAAa;EAClB,SAAS,4BAA4B;EACrC,aAAa,0BAA0B;EACxC,CAAC;;;;ACjBJ,SAAgB,uBAAgD;AAC9D,QAAO,eAAe;EACpB,MAAM;EACN,SAAS;EACT,OAAO;EACP,UAAU;EACV,UAAU,CAAC,EAAE,KAAK,cAAc,CAAC;EACjC,QAAQ;AACN,UAAO,CAAC,cAAc,EAAE;;EAE3B,CAAC;;;;;;;ACFJ,SAAgB,mBAAwC;AACtD,QAAO,MACL,sBAAsB,EACtB,2BAA2B,EAC3B,0BAA0B,EAC1B,wBAAwB,CACzB"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"prosekit-extensions-bold.d.ts","names":[],"sources":["../src/bold/bold-commands.ts","../src/bold/bold-input-rule.ts","../src/bold/bold-keymap.ts","../src/bold/bold-spec.ts","../src/bold/bold.ts"],"mappings":";;;;;;;KAKY,qBAAA,GAAwB,SAAA;EAClC,QAAA;IACE,UAAA;EAAA;AAAA;;;;iBAOY,kBAAA,CAAA,GAAsB,qBAAA;;;;;;iBCPtB,mBAAA,CAAA,GAAuB,cAAA;;;;;;iBCFvB,gBAAA,CAAA,GAAoB,cAAA;;;;;AFApC;KGCY,iBAAA,GAAoB,SAAA;EAC9B,KAAA;IACE,IAAA,EAAM,KAAA;EAAA;AAAA;;;;iBAOM,cAAA,CAAA,GAAkB,iBAAA;;;;AHVlC;;KIKY,aAAA,GAAgB,KAAA,EAAO,iBAAA,EAAmB,qBAAA;;;;iBAKtC,UAAA,CAAA,GAAc,aAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"prosekit-extensions-bold.js","names":[],"sources":["../src/bold/bold-commands.ts","../src/bold/bold-input-rule.ts","../src/bold/bold-keymap.ts","../src/bold/bold-spec.ts","../src/bold/bold.ts"],"sourcesContent":["import { defineCommands, toggleMark, type Extension } from '@prosekit/core'\n\n/**\n * @internal\n */\nexport type BoldCommandsExtension = Extension<{\n Commands: {\n toggleBold: []\n }\n}>\n\n/**\n * @internal\n */\nexport function defineBoldCommands(): BoldCommandsExtension {\n return defineCommands({\n toggleBold: () => toggleMark({ type: 'bold' }),\n })\n}\n","import { canUseRegexLookbehind, type PlainExtension } from '@prosekit/core'\n\nimport { defineMarkInputRule } from '../input-rule/index.ts'\n\n/**\n * @internal\n */\nexport function defineBoldInputRule(): PlainExtension {\n return defineMarkInputRule({\n regex: canUseRegexLookbehind()\n ? /(?<=\\s|^)\\*\\*([^\\s*]|[^\\s*][^*]*[^\\s*])\\*\\*$/\n : /\\*\\*([^\\s*]|[^\\s*][^*]*[^\\s*])\\*\\*$/,\n type: 'bold',\n })\n}\n","import { defineKeymap, toggleMark, type PlainExtension } from '@prosekit/core'\n\n/**\n * @internal\n */\nexport function defineBoldKeymap(): PlainExtension {\n return defineKeymap({\n 'Mod-b': toggleMark({ type: 'bold' }),\n })\n}\n","import { defineMarkSpec, type Extension } from '@prosekit/core'\nimport type { Attrs } from '@prosekit/pm/model'\n\n/**\n * @internal\n */\nexport type BoldSpecExtension = Extension<{\n Marks: {\n bold: Attrs\n }\n}>\n\n/**\n * @internal\n */\nexport function defineBoldSpec(): BoldSpecExtension {\n return defineMarkSpec({\n name: 'bold',\n parseDOM: [\n { tag: 'strong' },\n // This works around a Google Docs misbehavior where\n // pasted content will be inexplicably wrapped in `<b>`\n // tags with a font-weight normal.\n {\n tag: 'b',\n getAttrs: (node: string | HTMLElement): null | false => {\n return (\n typeof node !== 'string'\n && node.style.fontWeight !== 'normal'\n && null\n )\n },\n },\n { style: 'font-weight=400', clearMark: (m) => m.type.name == 'strong' },\n {\n style: 'font-weight',\n getAttrs: (value: string | HTMLElement): null | false => {\n return (\n typeof value === 'string'\n && /^(bold(er)?|[5-9]\\d{2,})$/.test(value)\n && null\n )\n },\n },\n ],\n toDOM() {\n return ['strong', 0]\n },\n })\n}\n","import { union, type Union } from '@prosekit/core'\n\nimport { defineBoldCommands, type BoldCommandsExtension } from './bold-commands.ts'\nimport { defineBoldInputRule } from './bold-input-rule.ts'\nimport { defineBoldKeymap } from './bold-keymap.ts'\nimport { defineBoldSpec, type BoldSpecExtension } from './bold-spec.ts'\n\n/**\n * @internal\n */\nexport type BoldExtension = Union<[BoldSpecExtension, BoldCommandsExtension]>\n\n/**\n * @public\n */\nexport function defineBold(): BoldExtension {\n return union(\n defineBoldSpec(),\n defineBoldCommands(),\n defineBoldKeymap(),\n defineBoldInputRule(),\n )\n}\n"],"mappings":";;;;;;AAcA,SAAgB,qBAA4C;AAC1D,QAAO,eAAe,EACpB,kBAAkB,WAAW,EAAE,MAAM,QAAQ,CAAC,EAC/C,CAAC;;;;;;;ACVJ,SAAgB,sBAAsC;AACpD,QAAO,oBAAoB;EACzB,OAAO,uBAAuB,GAC1B,iDACA;EACJ,MAAM;EACP,CAAC;;;;;;;ACRJ,SAAgB,mBAAmC;AACjD,QAAO,aAAa,EAClB,SAAS,WAAW,EAAE,MAAM,QAAQ,CAAC,EACtC,CAAC;;;;;;;ACOJ,SAAgB,iBAAoC;AAClD,QAAO,eAAe;EACpB,MAAM;EACN,UAAU;GACR,EAAE,KAAK,UAAU;GAIjB;IACE,KAAK;IACL,WAAW,SAA6C;AACtD,YACE,OAAO,SAAS,YACb,KAAK,MAAM,eAAe,YAC1B;;IAGR;GACD;IAAE,OAAO;IAAmB,YAAY,MAAM,EAAE,KAAK,QAAQ;IAAU;GACvE;IACE,OAAO;IACP,WAAW,UAA8C;AACvD,YACE,OAAO,UAAU,YACd,4BAA4B,KAAK,MAAM,IACvC;;IAGR;GACF;EACD,QAAQ;AACN,UAAO,CAAC,UAAU,EAAE;;EAEvB,CAAC;;;;;;;ACjCJ,SAAgB,aAA4B;AAC1C,QAAO,MACL,gBAAgB,EAChB,oBAAoB,EACpB,kBAAkB,EAClB,qBAAqB,CACtB"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"prosekit-extensions-code-block.d.ts","names":[],"sources":["../src/code-block/code-block-types.ts","../src/code-block/code-block-commands.ts","../src/code-block/code-block-highlight.ts","../src/code-block/code-block-input-rule.ts","../src/code-block/code-block-keymap.ts","../src/code-block/shiki-highlighter-chunk.ts","../src/code-block/code-block-shiki.ts","../src/code-block/code-block-spec.ts","../src/code-block/code-block.ts"],"mappings":";;;;;;;;;;UAKiB,cAAA;EACf,QAAA;AAAA;;;;;;KCCU,0BAAA,GAA6B,SAAA;EACvC,QAAA;IACE,YAAA,GAAe,KAAA,GAAQ,cAAA;IACvB,eAAA,GAAkB,KAAA,GAAQ,cAAA;IAC1B,eAAA,GAAkB,KAAA,GAAQ,cAAA;IAC1B,iBAAA,GAAoB,KAAA,EAAO,cAAA;EAAA;AAAA;AAL/B;;;;;AAAA,iBAcgB,uBAAA,CAAA,GAA2B,0BAAA;;;;;;ADhB3C;;KEGY,eAAA,GAAkB,MAAA;;;;KAKlB,yBAAA;;ADNZ;;ECUE,MAAA,EAAQ,eAAA;EDRiB;;;;;ECczB,SAAA;AAAA;;;;;;;;;;;iBAac,wBAAA,CAAA;EACd,MAAA;EACA;AAAA,GACC,yBAAA,GAA4B,SAAA;;;;;;;AFlC/B;iBGOgB,wBAAA,CAAA,GAA4B,cAAA;;;;;;iBAa5B,wBAAA,CAAA,GAA4B,cAAA;;;;;;iBCnB5B,qBAAA,CAAA,GAAyB,cAAA;;;UCGxB,uBAAA,SAAgC,yBAAA,CAA0B,eAAA,EAAiB,YAAA;;;;ALJ5F;;;;UMQiB,qBAAA,SAA8B,IAAA,CAAK,uBAAA;;;;ALNpD;;EKYE,SAAA;ELVyB;;;;;;EKkBzB,MAAA,GAAS,iBAAA;ELpB8B;;;;;EK2BvC,KAAA,IAAS,oBAAA,GAAuB,eAAA;ELxBZ;;;EK6BpB,MAAA,GAAS,uBAAA;AAAA;;;;;;ALlBX;;;;;;;iBKiCgB,oBAAA,CAAA;EACd,SAAA;EACA,MAAA;EACA,KAAA;EAAA,GACG;AAAA,IACF,qBAAA,GAA6B,SAAA;;;;;;KCpDpB,sBAAA,GAAyB,SAAA;EACnC,KAAA;IACE,SAAA,EAAW,cAAA;EAAA;AAAA;;;;ANFf;;iBMWgB,mBAAA,CAAA,GAAuB,sBAAA;;;;;APbvC;KQKY,kBAAA,GAAqB,KAAA,EAC9B,sBAAA,EAAwB,0BAAA;;;;APJ3B;;;;;;;;iBOkBgB,eAAA,CAAA,GAAmB,kBAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"prosekit-extensions-code-block.js","names":[],"sources":["../src/code-block/code-block-commands.ts","../src/code-block/code-block-highlight.ts","../src/code-block/code-block-input-rule.ts","../src/code-block/code-block-keymap.ts","../src/code-block/shiki-highlighter.ts","../src/code-block/shiki-parser.ts","../src/code-block/code-block-shiki.ts","../src/code-block/code-block-spec.ts","../src/code-block/code-block.ts"],"sourcesContent":["import { defineCommands, insertNode, setBlockType, setNodeAttrs, toggleNode, type Extension } from '@prosekit/core'\n\nimport type { CodeBlockAttrs } from './code-block-types.ts'\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 { definePlugin, type Extension } from '@prosekit/core'\nimport { createHighlightPlugin, type Parser } 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 /**\n * A parser instance from the `prosemirror-highlight` package.\n */\n parser: HighlightParser\n /**\n * ProseMirror node types to highlight.\n *\n * @default ['codeBlock', 'mathBlock']\n */\n nodeTypes?: string[]\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 nodeTypes = ['codeBlock', 'mathBlock'],\n}: CodeBlockHighlightOptions): Extension {\n return definePlugin(\n createHighlightPlugin({ parser, nodeTypes }),\n )\n}\n","import type { PlainExtension } from '@prosekit/core'\n\nimport { defineTextBlockEnterRule } from '../enter-rule/index.ts'\nimport { defineTextBlockInputRule } from '../input-rule/index.ts'\n\nimport type { CodeBlockAttrs } from './code-block-types.ts'\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 { defaultBlockAt, defineKeymap, type PlainExtension } from '@prosekit/core'\nimport { TextSelection, type Command } 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 type { HighlighterOptions, HighlighterResult } from './shiki-highlighter-chunk.ts'\n\nlet loaded: ((options: HighlighterOptions) => HighlighterResult) | undefined\n\nasync function load() {\n const { createOrGetHighlighter } = await import('./shiki-highlighter-chunk.ts')\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.ts'\nimport { createOrGetHighlighter, type HighlighterOptions } from './shiki-highlighter.ts'\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.ts'\nimport type { ShikiBundledLanguage, ShikiBundledTheme } from './shiki-bundle.ts'\nimport type { ShikiHighlighterOptions } from './shiki-highlighter-chunk.ts'\nimport { createLazyParser } from './shiki-parser.ts'\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 * ProseMirror node types to highlight.\n *\n * @default ['codeBlock', 'mathBlock']\n */\n nodeTypes?: string[]\n\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 nodeTypes,\n themes = ['one-dark-pro'],\n langs = ['text'],\n ...rest\n}: CodeBlockShikiOptions = {}): Extension {\n const parser = createLazyParser({ themes, langs, ...rest })\n return defineCodeBlockHighlight({ parser, nodeTypes })\n}\n","import { defineNodeSpec, type Extension } from '@prosekit/core'\n\nimport type { CodeBlockAttrs } from './code-block-types.ts'\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 { union, type Union } from '@prosekit/core'\n\nimport { defineCodeBlockCommands, type CodeBlockCommandsExtension } from './code-block-commands.ts'\nimport { defineCodeBlockEnterRule, defineCodeBlockInputRule } from './code-block-input-rule.ts'\nimport { defineCodeBlockKeymap } from './code-block-keymap.ts'\nimport { defineCodeBlockSpec, type CodeBlockSpecExtension } from './code-block-spec.ts'\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"],"mappings":";;;;;;;;;;;;;AAqBA,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;;;;;;;;;;;;;;ACCJ,SAAgB,yBAAyB,EACvC,QACA,YAAY,CAAC,aAAa,YAAY,IACC;AACvC,QAAO,aACL,sBAAsB;EAAE;EAAQ;EAAW,CAAC,CAC7C;;;;;;;;;AC9BH,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;;;;;;;AC5BrC,SAAgB,wBAAwC;AACtD,QAAO,aAAa,EAClB,OAAO,gBACR,CAAC;;;;;;AAOJ,MAAM,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;;;;AClDT,IAAI;AAEJ,eAAe,OAAO;CACpB,MAAM,EAAE,2BAA2B,MAAM,OAAO;AAChD,UAAS;;AAGX,SAAgB,uBACd,SACmB;AACnB,KAAI,CAAC,OACH,QAAO,EAAE,SAAS,MAAM,EAAE;AAE5B,QAAO,OAAO,QAAQ;;;;;;;ACNxB,SAAgB,iBACd,oBACQ;CACR,IAAI;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;;;;;;;;;;;;;;;;;ACwB1B,SAAgB,qBAAqB,EACnC,WACA,SAAS,CAAC,eAAe,EACzB,QAAQ,CAAC,OAAO,EAChB,GAAG,SACsB,EAAE,EAAa;AAExC,QAAO,yBAAyB;EAAE,QADnB,iBAAiB;GAAE;GAAQ;GAAO,GAAG;GAAM,CAAC;EACjB;EAAW,CAAC;;;;;;;;;AC3CxD,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,KAAA,GAAW;IAE1C;KAAC;KAAQ,EAAE,OAAO,WAAW,YAAY,aAAa,KAAA,GAAW;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;;;;;;;;;;;;;;;ACzCT,SAAgB,kBAAsC;AACpD,QAAO,MACL,qBAAqB,EACrB,0BAA0B,EAC1B,0BAA0B,EAC1B,uBAAuB,EACvB,yBAAyB,CAC1B"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"prosekit-extensions-code.d.ts","names":[],"sources":["../src/code/code-commands.ts","../src/code/code-input-rule.ts","../src/code/code-keymap.ts","../src/code/code-spec.ts","../src/code/code.ts"],"mappings":";;;;;;;KAKY,qBAAA,GAAwB,SAAA;EAClC,QAAA;IACE,UAAA;EAAA;AAAA;;;;iBAOY,kBAAA,CAAA,GAAsB,qBAAA;;;;;;iBCPtB,mBAAA,CAAA,GAAuB,cAAA;;;;;;iBCFvB,gBAAA,CAAA,GAAoB,cAAA;;;;;AFApC;KGCY,iBAAA,GAAoB,SAAA;EAC9B,KAAA;IACE,IAAA,EAAM,KAAA;EAAA;AAAA;;;;iBAOM,cAAA,CAAA,GAAkB,iBAAA;;;;AHVlC;;KIKY,aAAA,GAAgB,KAAA,EAAO,iBAAA,EAAmB,qBAAA;;;;iBAKtC,UAAA,CAAA,GAAc,aAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"prosekit-extensions-code.js","names":[],"sources":["../src/code/code-commands.ts","../src/code/code-input-rule.ts","../src/code/code-keymap.ts","../src/code/code-spec.ts","../src/code/code.ts"],"sourcesContent":["import { defineCommands, toggleMark, type Extension } from '@prosekit/core'\n\n/**\n * @internal\n */\nexport type CodeCommandsExtension = Extension<{\n Commands: {\n toggleCode: []\n }\n}>\n\n/**\n * @internal\n */\nexport function defineCodeCommands(): CodeCommandsExtension {\n return defineCommands({\n toggleCode: () => toggleMark({ type: 'code' }),\n })\n}\n","import { canUseRegexLookbehind, type PlainExtension } from '@prosekit/core'\n\nimport { defineMarkInputRule } from '../input-rule/index.ts'\n\n/**\n * @internal\n */\nexport function defineCodeInputRule(): PlainExtension {\n return defineMarkInputRule({\n regex: canUseRegexLookbehind()\n ? /(?<=\\s|^)`([^\\s`]|[^\\s`][^`]*[^\\s`])`$/\n : /`([^\\s`]|[^\\s`][^`]*[^\\s`])`$/,\n type: 'code',\n })\n}\n","import { defineKeymap, toggleMark, type PlainExtension } from '@prosekit/core'\n\n/**\n * @internal\n */\nexport function defineCodeKeymap(): PlainExtension {\n return defineKeymap({\n 'Mod-e': toggleMark({ type: 'code' }),\n })\n}\n","import { defineMarkSpec, type Extension } from '@prosekit/core'\nimport type { Attrs } from '@prosekit/pm/model'\n\n/**\n * @internal\n */\nexport type CodeSpecExtension = Extension<{\n Marks: {\n code: Attrs\n }\n}>\n\n/**\n * @internal\n */\nexport function defineCodeSpec(): CodeSpecExtension {\n return defineMarkSpec({\n name: 'code',\n parseDOM: [{ tag: 'code' }],\n code: true,\n toDOM() {\n return ['code', 0]\n },\n })\n}\n","import { union, type Union } from '@prosekit/core'\n\nimport { defineCodeCommands, type CodeCommandsExtension } from './code-commands.ts'\nimport { defineCodeInputRule } from './code-input-rule.ts'\nimport { defineCodeKeymap } from './code-keymap.ts'\nimport { defineCodeSpec, type CodeSpecExtension } from './code-spec.ts'\n\n/**\n * @internal\n */\nexport type CodeExtension = Union<[CodeSpecExtension, CodeCommandsExtension]>\n\n/**\n * @public\n */\nexport function defineCode(): CodeExtension {\n return union(\n defineCodeSpec(),\n defineCodeCommands(),\n defineCodeKeymap(),\n defineCodeInputRule(),\n )\n}\n"],"mappings":";;;;;;AAcA,SAAgB,qBAA4C;AAC1D,QAAO,eAAe,EACpB,kBAAkB,WAAW,EAAE,MAAM,QAAQ,CAAC,EAC/C,CAAC;;;;;;;ACVJ,SAAgB,sBAAsC;AACpD,QAAO,oBAAoB;EACzB,OAAO,uBAAuB,GAC1B,2CACA;EACJ,MAAM;EACP,CAAC;;;;;;;ACRJ,SAAgB,mBAAmC;AACjD,QAAO,aAAa,EAClB,SAAS,WAAW,EAAE,MAAM,QAAQ,CAAC,EACtC,CAAC;;;;;;;ACOJ,SAAgB,iBAAoC;AAClD,QAAO,eAAe;EACpB,MAAM;EACN,UAAU,CAAC,EAAE,KAAK,QAAQ,CAAC;EAC3B,MAAM;EACN,QAAQ;AACN,UAAO,CAAC,QAAQ,EAAE;;EAErB,CAAC;;;;;;;ACRJ,SAAgB,aAA4B;AAC1C,QAAO,MACL,gBAAgB,EAChB,oBAAoB,EACpB,kBAAkB,EAClB,qBAAqB,CACtB"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"prosekit-extensions-commit.d.ts","names":[],"sources":["../src/commit/index.ts"],"mappings":";;;;;;;AAEmF;UAQzE,MAAA;;;;EAIR,GAAA,EAAK,QAAA;EASU;;;EALf,MAAA,EAAQ,QAAA;EAAR;;;;EAKA,KAAA,EAAO,QAAA;AAAA;AAAQ;;;AAAA,iBA2MR,kBAAA,CAAmB,MAAA,EAAQ,MAAA,GAAS,cAAA;AAAA,cAOvC,cAAA;EAAA,QACI,MAAA;EAAA,QACA,GAAA;EAAA,QACA,KAAA;EAViD;AAAA;;;EAgBzD,MAAA,CAAA,GAAU,MAAA;EAsBA;;;EAAV,IAAA,CAAK,GAAA,EAAK,eAAA;EA9BF;;;EAuCR,KAAA,CAAM,EAAA,EAAI,WAAA;AAAA;;;;iBASH,oBAAA,CAAqB,cAAA,EAAgB,cAAA,GAAiB,cAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"prosekit-extensions-commit.js","names":[],"sources":["../src/commit/index.ts"],"sourcesContent":["import { defineDefaultState, definePlugin, jsonFromNode, union, type NodeJSON, type PlainExtension, type StepJSON } from '@prosekit/core'\nimport { DOMSerializer, Fragment, Slice, type ProseMirrorNode } from '@prosekit/pm/model'\nimport { PluginKey, ProseMirrorPlugin, type Transaction } from '@prosekit/pm/state'\nimport { Step } from '@prosekit/pm/transform'\nimport { Decoration, DecorationSet, type EditorView } from '@prosekit/pm/view'\nimport { ChangeSet, type Change } from 'prosemirror-changeset'\n\n/**\n * A JSON representation of a commit.\n */\ninterface Commit {\n /**\n * The current doc node in the JSON format\n */\n doc: NodeJSON\n /**\n * The parent node in the JSON format\n */\n parent: NodeJSON\n /**\n * An array of steps in the JSON format that transform the parent node to the\n * current doc node.\n */\n steps: StepJSON[]\n}\n\nfunction getChanges(\n doc: ProseMirrorNode,\n parent: ProseMirrorNode,\n steps: Step[],\n): readonly Change[] {\n const initSet = ChangeSet.create(parent)\n const currSet = initSet.addSteps(\n doc,\n steps.map((step) => step.getMap()),\n null,\n )\n return currSet.changes\n}\n\nfunction renderDivWeight(view: EditorView): HTMLElement {\n const document = view.dom.ownerDocument\n return document.createElement('div')\n}\n\nfunction decorateDeletionSlice(\n slice: Slice,\n): Array<(view: EditorView) => HTMLElement> {\n // Get the fragment of the deleted content\n let { openStart, openEnd, content } = slice\n\n while (openStart > 0 && openEnd > 0 && content.childCount === 1) {\n openStart--\n openEnd--\n content = content.child(0).content\n }\n\n // Nothing to render\n if (content.childCount === 0) {\n return []\n }\n\n // For example, if the slice is\n // {\n // openStart: 1,\n // openEnd: 1,\n // content: <p>Hello</p><p>World</p>\n // }\n // We should render the following decorations:\n // <span>Hello</span>\n // <div></div>\n // <span>World</span>\n if (openStart > 0 && openEnd > 0 && content.childCount === 2) {\n const head = Fragment.from([content.child(0)])\n const tail = Fragment.from([content.child(1)])\n return [\n ...decorateDeletionSlice(new Slice(head, openStart, openStart)),\n renderDivWeight,\n ...decorateDeletionSlice(new Slice(tail, openEnd, openEnd)),\n ]\n }\n\n // For example, if the slice is\n // {\n // openStart: 1,\n // openEnd: 0,\n // content: <p>Hello</p><p>World</p>\n // }\n // We should render the following decorations:\n // <span>Hello</span>\n // <div><p>World</p></div>\n if (openStart > 0 && content.childCount >= 2) {\n const nodes = content.content\n const head = Fragment.from(nodes.slice(0, 1))\n const body = Fragment.from(nodes.slice(1))\n\n return [\n ...decorateDeletionSlice(new Slice(head, openStart, openStart)),\n ...decorateDeletionSlice(new Slice(body, 0, openEnd)),\n ]\n }\n\n // For example, if the slice is\n // {\n // openStart: 0,\n // openEnd: 1,\n // content: <p>Hello</p><p>World</p>\n // }\n // We should render the following decorations:\n // <div><p>Hello</p></div>\n // <span>World</span>\n if (openEnd > 0 && content.childCount >= 2) {\n const nodes = content.content\n const body = Fragment.from(nodes.slice(0, -1))\n const tail = Fragment.from(nodes.slice(-1))\n return [\n ...decorateDeletionSlice(new Slice(body, openStart, 0)),\n ...decorateDeletionSlice(new Slice(tail, openEnd, openEnd)),\n ]\n }\n\n const schema = content.child(0).type.schema\n const isInline = content.child(0).isInline\n\n const render = (view: EditorView): HTMLElement => {\n const document = view.dom.ownerDocument\n\n // Render the fragment to HTML\n const element = document.createElement(isInline ? 'span' : 'div')\n const serializer = DOMSerializer.fromSchema(schema)\n serializer.serializeFragment(content, { document }, element)\n\n // Add the class to the element\n element.classList.add('prosekit-commit-deletion')\n return element\n }\n\n return [render]\n}\n\nfunction decorateDeletion(\n /** The doc node before the deletion */\n doc: ProseMirrorNode,\n /** The start position of the deleted text in the doc node */\n from: number,\n /** The end position of the deleted text in the doc node */\n to: number,\n /** The insert position of the decoration in the doc node after the change */\n pos: number,\n): Decoration[] {\n const slice = doc.slice(from, to)\n\n const renders = decorateDeletionSlice(slice)\n const count = renders.length\n\n return renders.map((render, index) =>\n Decoration.widget(pos, render, {\n side: -20 - count + index,\n // Ensure the text in the decoration is able to be selected.\n ignoreSelection: true,\n })\n )\n}\n\nfunction decorateAddition(\n /** The start position of the inserted text in the doc node */\n from: number,\n /** The end position of the inserted text in the doc node */\n to: number,\n): Decoration {\n return Decoration.inline(from, to, { class: 'prosekit-commit-addition' })\n}\n\nfunction decorateChange(prev: ProseMirrorNode, change: Change): Decoration[] {\n const { fromA, toA, fromB, toB } = change\n const decorations: Decoration[] = []\n\n if (fromA < toA) {\n decorations.push(...decorateDeletion(prev, fromA, toA, fromB))\n }\n if (fromB < toB) {\n decorations.push(decorateAddition(fromB, toB))\n }\n\n return decorations\n}\n\nfunction decorateCommit(\n doc: ProseMirrorNode,\n parent: ProseMirrorNode,\n steps: Step[],\n): DecorationSet {\n const changes = getChanges(doc, parent, steps)\n const decorations = changes.flatMap((change) => decorateChange(parent, change))\n return DecorationSet.create(doc, decorations)\n}\n\nfunction defineCommitDecoration(commit: Commit): PlainExtension {\n const key = new PluginKey<DecorationSet>('prosekit-commit-decoration')\n\n return definePlugin(({ schema }): ProseMirrorPlugin => {\n const parent = schema.nodeFromJSON(commit.parent)\n const steps = commit.steps.map((step) => Step.fromJSON(schema, step))\n\n return new ProseMirrorPlugin({\n key,\n state: {\n init: (_, instance): DecorationSet => {\n return decorateCommit(instance.doc, parent, steps)\n },\n apply: (tr, deco: DecorationSet): DecorationSet => {\n return deco.map(tr.mapping, tr.doc)\n },\n },\n props: {\n decorations: (state): DecorationSet | undefined => {\n return key.getState(state)\n },\n },\n })\n })\n}\n\n/**\n * Define an extension to display the changes from the given commit in the editor.\n */\nfunction defineCommitViewer(commit: Commit): PlainExtension {\n return union(\n defineDefaultState({ defaultContent: commit.doc }),\n defineCommitDecoration(commit),\n )\n}\n\nclass CommitRecorder {\n private parent: ProseMirrorNode | null = null\n private doc: ProseMirrorNode | null = null\n private steps: Step[] = []\n\n /**\n * Return a commit object including all changes since the last commit. `null`\n * will be returned if there is no change.\n */\n commit(): Commit | null {\n if (\n !this.parent\n || !this.doc\n || this.steps.length === 0\n || this.parent.eq(this.doc)\n ) {\n return null\n }\n\n const commit: Commit = {\n doc: jsonFromNode(this.doc),\n parent: jsonFromNode(this.parent),\n steps: this.steps.map((step) => step.toJSON() as StepJSON),\n }\n this.init(this.doc)\n return commit\n }\n\n /**\n * @internal\n */\n init(doc: ProseMirrorNode): void {\n this.doc = doc\n this.parent = doc\n this.steps = []\n }\n\n /**\n * @internal\n */\n apply(tr: Transaction): void {\n this.steps.push(...tr.steps)\n this.doc = tr.doc\n }\n}\n\n/**\n * Define an extension that can record the changes in the editor.\n */\nfunction defineCommitRecorder(commitRecorder: CommitRecorder): PlainExtension {\n const key = new PluginKey<DecorationSet>('prosekit-commit-recorder')\n\n return definePlugin(\n new ProseMirrorPlugin({\n key,\n state: {\n init: (_, state): void => {\n commitRecorder.init(state.doc)\n },\n apply: (tr): void => {\n commitRecorder.apply(tr)\n },\n },\n }),\n )\n}\n\nexport { CommitRecorder, defineCommitRecorder, defineCommitViewer, type Commit }\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"prosekit-extensions-doc.d.ts","names":[],"sources":["../src/doc/index.ts"],"mappings":";;;;;;AAMA;KAAY,YAAA,GAAe,SAAA;EAAY,KAAA;IAAS,GAAA,EAAK,KAAA;EAAA;AAAA;;;;iBAKrC,SAAA,CAAA,GAAa,YAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"prosekit-extensions-doc.js","names":[],"sources":["../src/doc/index.ts"],"sourcesContent":["import { defineNodeSpec, type Extension } from '@prosekit/core'\nimport type { Attrs } from '@prosekit/pm/model'\n\n/**\n * @internal\n */\nexport type DocExtension = Extension<{ Nodes: { doc: Attrs } }>\n\n/**\n * @public\n */\nexport function defineDoc(): DocExtension {\n return defineNodeSpec({\n name: 'doc',\n content: 'block+',\n topNode: true,\n })\n}\n"],"mappings":";;;;;AAWA,SAAgB,YAA0B;AACxC,QAAO,eAAe;EACpB,MAAM;EACN,SAAS;EACT,SAAS;EACV,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"prosekit-extensions-drop-cursor.d.ts","names":[],"sources":["../src/drop-cursor/drop-cursor.ts"],"mappings":";;;UAGiB,iBAAA;;AAAjB;;;;EAME,KAAA;EAOA;;;;AAWF;EAXE,KAAA;;;;EAKA,KAAA;AAAA;;;;KAMU,mBAAA,GAAsB,cAAA;;;;;;;;;;iBAWlB,gBAAA,CACd,OAAA,GAAU,iBAAA,GACT,mBAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"prosekit-extensions-drop-cursor.js","names":[],"sources":["../src/drop-cursor/drop-cursor.ts"],"sourcesContent":["import { definePlugin, type PlainExtension } from '@prosekit/core'\nimport { dropCursor } from 'prosemirror-dropcursor'\n\nexport interface DropCursorOptions {\n /**\n * The color of the cursor. Use `false` to apply no color and rely only on class.\n *\n * @default 'black'\n */\n color?: string | false\n\n /**\n * The precise width of the cursor in pixels.\n *\n * @default 1\n */\n width?: number\n\n /**\n * A CSS class name to add to the cursor element.\n */\n class?: string\n}\n\n/**\n * @internal\n */\nexport type DropCursorExtension = PlainExtension\n\n/**\n * Show up a decoration at the drop position when something is dragged over the editor.\n *\n * See [prosemirror-dropcursor](https://github.com/ProseMirror/prosemirror-dropcursor) for more information.\n *\n * You probably want to use `<DropIndicator />` component instead of this extension.\n *\n * @public\n */\nexport function defineDropCursor(\n options?: DropCursorOptions,\n): DropCursorExtension {\n return definePlugin(() => dropCursor(options))\n}\n"],"mappings":";;;;;;;;;;;;AAsCA,SAAgB,iBACd,SACqB;AACrB,QAAO,mBAAmB,WAAW,QAAQ,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"prosekit-extensions-drop-indicator.d.ts","names":[],"sources":["../src/drop-indicator/drop-indicator.ts"],"mappings":";;;;;;AAQA;KAAY,sBAAA,GAAyB,cAAA;;;;AAerC;;;;;;;;;AAWA;iBAXgB,mBAAA,CACd,OAAA,GAAU,oBAAA,GACT,sBAAA;;;;;;UASc,oBAAA,SAA6B,0BAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"prosekit-extensions-enter-rule.d.ts","names":[],"sources":["../src/enter-rule/index.ts"],"mappings":";;;;;AAiBA;;;;UAAiB,gBAAA,SAAyB,SAAA;;;;;AAkB1C;UAXiB,yBAAA,SAAkC,2BAAA;;;;;;;AAwBnD;;;iBAbgB,eAAA,CAAgB,OAAA,EAAS,gBAAA,GAAmB,cAAA;;;;;;;;;;iBAa5C,wBAAA,CAAyB,OAAA,EAAS,yBAAA,GAA4B,cAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"prosekit-extensions-enter-rule.js","names":[],"sources":["../src/enter-rule/index.ts"],"sourcesContent":["import { defineFacet, defineFacetPayload, pluginFacet, type PlainExtension, type PluginPayload } from '@prosekit/core'\nimport {\n createEnterRulePlugin,\n createTextBlockEnterRule,\n type EnterRule,\n type EnterRuleHandler,\n type EnterRuleHandlerOptions,\n type TextBlockEnterRuleOptions as TextBlockEnterRuleOptionsBase,\n} from 'prosemirror-enter-rules'\n\nexport type { EnterRuleHandler, EnterRuleHandlerOptions }\n\n/**\n * Options for {@link defineEnterRule}.\n *\n * @public\n */\nexport interface EnterRuleOptions extends EnterRule {}\n\n/**\n * Options for {@link defineTextBlockEnterRule}.\n *\n * @public\n */\nexport interface TextBlockEnterRuleOptions extends TextBlockEnterRuleOptionsBase {}\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(options: EnterRuleOptions): PlainExtension {\n return defineFacetPayload(enterRuleFacet, [options]) 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(options: TextBlockEnterRuleOptions): PlainExtension {\n return defineEnterRule(createTextBlockEnterRule(options))\n}\n\nconst enterRuleFacet = defineFacet<EnterRule, PluginPayload>({\n reducer: (rules: EnterRule[]): PluginPayload => {\n return createEnterRulePlugin({ rules })\n },\n\n parent: pluginFacet,\n})\n"],"mappings":";;;;;;;;;;;;AAmCA,SAAgB,gBAAgB,SAA2C;AACzE,QAAO,mBAAmB,gBAAgB,CAAC,QAAQ,CAAC;;;;;;;;;;;AAYtD,SAAgB,yBAAyB,SAAoD;AAC3F,QAAO,gBAAgB,yBAAyB,QAAQ,CAAC;;AAG3D,MAAM,iBAAiB,YAAsC;CAC3D,UAAU,UAAsC;AAC9C,SAAO,sBAAsB,EAAE,OAAO,CAAC;;CAGzC,QAAQ;CACT,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"prosekit-extensions-gap-cursor.d.ts","names":[],"sources":["../src/gap-cursor/gap-cursor.ts"],"mappings":";;;;;AAMA;KAAY,kBAAA,GAAqB,cAAA;;;;AAgBjC;;;;;;;;;;;iBAAgB,eAAA,CAAA,GAAmB,kBAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"prosekit-extensions-gap-cursor.js","names":[],"sources":["../src/gap-cursor/gap-cursor.ts"],"sourcesContent":["import { definePlugin, type PlainExtension } from '@prosekit/core'\nimport { gapCursor } from 'prosemirror-gapcursor'\n\n/**\n * @internal\n */\nexport type GapCursorExtension = PlainExtension\n\n/**\n * Capture clicks near and arrow-key-motion past places that don't have a\n * normally selectable position nearby, and create a gap cursor selection for\n * them. The cursor is drawn as an element with class `ProseMirror-gapcursor`.\n *\n * You can either include `prosekit/extensions/gap-cursor.css` or add your own\n * styles to make it visible.\n *\n * See\n * [prosemirror-gapcursor](https://github.com/ProseMirror/prosemirror-gapcursor)\n * for more information.\n *\n * @public\n */\nexport function defineGapCursor(): GapCursorExtension {\n return definePlugin(() => gapCursor())\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAsBA,SAAgB,kBAAsC;AACpD,QAAO,mBAAmB,WAAW,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"prosekit-extensions-hard-break.d.ts","names":[],"sources":["../src/hard-break/hard-break-commands.ts","../src/hard-break/hard-break-keymap.ts","../src/hard-break/hard-break-spec.ts","../src/hard-break/hard-break.ts"],"mappings":";;;;;;;;KAMY,0BAAA,GAA6B,SAAA;EACvC,QAAA;IACE,eAAA;EAAA;AAAA;AAcJ;;;AAAA,iBAAgB,uBAAA,CAAA,GAA2B,0BAAA;;;;;;iBCf3B,qBAAA,CAAA,GAAyB,cAAA;;;;;;KCD7B,sBAAA,GAAyB,SAAA;EACnC,KAAA;IACE,SAAA,EAAW,KAAA;EAAA;AAAA;;;;iBAOC,mBAAA,CAAA,GAAuB,sBAAA;;;;;AFTvC;KGGY,kBAAA,GAAqB,KAAA,EAC9B,sBAAA,EAAwB,0BAAA;;;;iBAMX,eAAA,CAAA,GAAmB,kBAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"prosekit-extensions-hard-break.js","names":[],"sources":["../src/hard-break/hard-break-commands.ts","../src/hard-break/hard-break-keymap.ts","../src/hard-break/hard-break-spec.ts","../src/hard-break/hard-break.ts"],"sourcesContent":["import { defineCommands, insertNode, type Extension } from '@prosekit/core'\nimport type { Command } from '@prosekit/pm/state'\n\n/**\n * @internal\n */\nexport type HardBreakCommandsExtension = Extension<{\n Commands: {\n insertHardBreak: []\n }\n}>\n\n/**\n * @internal\n */\nexport function insertHardBreak(): Command {\n return insertNode({ type: 'hardBreak' })\n}\n\n/**\n * @internal\n */\nexport function defineHardBreakCommands(): HardBreakCommandsExtension {\n return defineCommands({\n insertHardBreak: insertHardBreak,\n })\n}\n","import { defineKeymap, type PlainExtension } from '@prosekit/core'\n\nimport { insertHardBreak } from './hard-break-commands.ts'\n\n/**\n * @internal\n */\nexport function defineHardBreakKeymap(): PlainExtension {\n return defineKeymap({\n 'Mod-Enter': insertHardBreak(),\n 'Shift-Enter': insertHardBreak(),\n })\n}\n","import { defineNodeSpec, type Extension } from '@prosekit/core'\nimport type { Attrs } from '@prosekit/pm/model'\n\n/**\n * @internal\n */\nexport type HardBreakSpecExtension = Extension<{\n Nodes: {\n hardBreak: Attrs\n }\n}>\n\n/**\n * @internal\n */\nexport function defineHardBreakSpec(): HardBreakSpecExtension {\n return defineNodeSpec({\n name: 'hardBreak',\n inline: true,\n selectable: false,\n leafText: () => '\\n',\n group: 'inline',\n parseDOM: [{ tag: 'br' }],\n toDOM() {\n return ['br']\n },\n })\n}\n","import { union, type Union } from '@prosekit/core'\n\nimport { defineHardBreakCommands, type HardBreakCommandsExtension } from './hard-break-commands.ts'\nimport { defineHardBreakKeymap } from './hard-break-keymap.ts'\nimport { defineHardBreakSpec, type HardBreakSpecExtension } from './hard-break-spec.ts'\n\n/**\n * @internal\n */\nexport type HardBreakExtension = Union<\n [HardBreakSpecExtension, HardBreakCommandsExtension]\n>\n\n/**\n * @public\n */\nexport function defineHardBreak(): HardBreakExtension {\n return union(\n defineHardBreakSpec(),\n defineHardBreakKeymap(),\n defineHardBreakCommands(),\n )\n}\n"],"mappings":";;;;;AAeA,SAAgB,kBAA2B;AACzC,QAAO,WAAW,EAAE,MAAM,aAAa,CAAC;;;;;AAM1C,SAAgB,0BAAsD;AACpE,QAAO,eAAe,EACH,iBAClB,CAAC;;;;;;;AClBJ,SAAgB,wBAAwC;AACtD,QAAO,aAAa;EAClB,aAAa,iBAAiB;EAC9B,eAAe,iBAAiB;EACjC,CAAC;;;;;;;ACIJ,SAAgB,sBAA8C;AAC5D,QAAO,eAAe;EACpB,MAAM;EACN,QAAQ;EACR,YAAY;EACZ,gBAAgB;EAChB,OAAO;EACP,UAAU,CAAC,EAAE,KAAK,MAAM,CAAC;EACzB,QAAQ;AACN,UAAO,CAAC,KAAK;;EAEhB,CAAC;;;;;;;ACVJ,SAAgB,kBAAsC;AACpD,QAAO,MACL,qBAAqB,EACrB,uBAAuB,EACvB,yBAAyB,CAC1B"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"prosekit-extensions-heading.d.ts","names":[],"sources":["../src/heading/heading-types.ts","../src/heading/heading-commands.ts","../src/heading/heading-input-rule.ts","../src/heading/heading-keymap.ts","../src/heading/heading-spec.ts","../src/heading/heading.ts"],"mappings":";;;UAAiB,YAAA;EACf,KAAA;AAAA;;;;AADF;;KCOY,wBAAA,GAA2B,SAAA;EACrC,QAAA;IACE,UAAA,GAAa,KAAA,GAAQ,YAAA;IACrB,aAAA,GAAgB,KAAA,GAAQ,YAAA;IACxB,aAAA,GAAgB,KAAA,GAAQ,YAAA;EAAA;AAAA;;;;iBAOZ,qBAAA,CAAA,GAAyB,wBAAA;;;;;ADlBzC;;;;iBEYgB,sBAAA,CAAA,GAA0B,cAAA;;;;;AFZ1C;iBGsBgB,mBAAA,CAAA,GAAuB,cAAA;;;;AHtBvC;;KIOY,oBAAA,GAAuB,SAAA;EACjC,KAAA;IACE,OAAA,EAAS,YAAA;EAAA;AAAA;;AHFb;;iBGSgB,iBAAA,CAAA,GAAqB,oBAAA;;;AJhBrC;;;AAAA,KKUY,gBAAA,GAAmB,KAAA,EAC5B,oBAAA,EAAsB,wBAAA;;AJJzB;;iBIUgB,aAAA,CAAA,GAAiB,gBAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"prosekit-extensions-heading.js","names":[],"sources":["../src/heading/heading-commands.ts","../src/heading/heading-input-rule.ts","../src/heading/heading-keymap.ts","../src/heading/heading-spec.ts","../src/heading/heading.ts"],"sourcesContent":["import { defineCommands, insertNode, setBlockType, toggleNode, type Extension } from '@prosekit/core'\n\nimport type { HeadingAttrs } from './heading-types.ts'\n\n/**\n * @internal\n */\nexport type HeadingCommandsExtension = Extension<{\n Commands: {\n setHeading: [attrs?: HeadingAttrs | undefined]\n insertHeading: [attrs?: HeadingAttrs | undefined]\n toggleHeading: [attrs?: HeadingAttrs | undefined]\n }\n}>\n\n/**\n * @internal\n */\nexport function defineHeadingCommands(): HeadingCommandsExtension {\n return defineCommands({\n setHeading: (attrs?: HeadingAttrs) => {\n return setBlockType({ type: 'heading', attrs })\n },\n insertHeading: (attrs?: HeadingAttrs) => {\n return insertNode({ type: 'heading', attrs })\n },\n toggleHeading: (attrs?: HeadingAttrs) => {\n return toggleNode({ type: 'heading', attrs })\n },\n })\n}\n","import type { PlainExtension } from '@prosekit/core'\n\nimport { defineTextBlockInputRule } from '../input-rule/index.ts'\n\nimport type { HeadingAttrs } from './heading-types.ts'\n\n/**\n * Converts the text block to a heading when `#` is typed at the start of a new\n * line followed by a space.\n *\n * @internal\n */\nexport function defineHeadingInputRule(): PlainExtension {\n return defineTextBlockInputRule({\n regex: /^(#{1,6})\\s$/,\n type: 'heading',\n attrs: (match) => {\n const level: number = match[1]?.length ?? 1\n return { level } satisfies HeadingAttrs\n },\n })\n}\n","import { defineKeymap, isAtBlockStart, toggleNode, unsetBlockType, withSkipCodeBlock, type PlainExtension } from '@prosekit/core'\nimport type { Command } from '@prosekit/pm/state'\n\nfunction toggleHeadingKeybinding(level: number): Command {\n return withSkipCodeBlock(toggleNode({ type: 'heading', attrs: { level } }))\n}\n\n/**\n * Set the block type to default (usually `paragraph`) when pressing Backspace at\n * the start of a heading block.\n */\nconst backspaceUnsetHeading: Command = (state, dispatch, view) => {\n const $pos = isAtBlockStart(state, view)\n if ($pos?.parent.type.name === 'heading') {\n return unsetBlockType()(state, dispatch, view)\n }\n return false\n}\n\n/**\n * @internal\n */\nexport function defineHeadingKeymap(): PlainExtension {\n return defineKeymap({\n 'Mod-Alt-1': toggleHeadingKeybinding(1),\n 'Mod-Alt-2': toggleHeadingKeybinding(2),\n 'Mod-Alt-3': toggleHeadingKeybinding(3),\n 'Mod-Alt-4': toggleHeadingKeybinding(4),\n 'Mod-Alt-5': toggleHeadingKeybinding(5),\n 'Mod-Alt-6': toggleHeadingKeybinding(6),\n 'Backspace': backspaceUnsetHeading,\n })\n}\n","import { defineNodeSpec, type Extension } from '@prosekit/core'\n\nimport type { HeadingAttrs } from './heading-types.ts'\n\n/**\n * @internal\n */\nexport type HeadingSpecExtension = Extension<{\n Nodes: {\n heading: HeadingAttrs\n }\n}>\n\n/**\n * @internal\n */\nexport function defineHeadingSpec(): HeadingSpecExtension {\n return defineNodeSpec({\n name: 'heading',\n attrs: { level: { default: 1, validate: 'number' } },\n content: 'inline*',\n group: 'block',\n defining: true,\n parseDOM: [\n { tag: 'h1', attrs: { level: 1 } },\n { tag: 'h2', attrs: { level: 2 } },\n { tag: 'h3', attrs: { level: 3 } },\n { tag: 'h4', attrs: { level: 4 } },\n { tag: 'h5', attrs: { level: 5 } },\n { tag: 'h6', attrs: { level: 6 } },\n ],\n toDOM(node) {\n return [`h${node.attrs.level}`, 0]\n },\n })\n}\n","import { union, type Union } from '@prosekit/core'\n\nimport { defineHeadingCommands, type HeadingCommandsExtension } from './heading-commands.ts'\nimport { defineHeadingInputRule } from './heading-input-rule.ts'\nimport { defineHeadingKeymap } from './heading-keymap.ts'\nimport { defineHeadingSpec, type HeadingSpecExtension } from './heading-spec.ts'\n\n/**\n * @internal\n */\nexport type HeadingExtension = Union<\n [HeadingSpecExtension, HeadingCommandsExtension]\n>\n\n/**\n * @public\n */\nexport function defineHeading(): HeadingExtension {\n return union(\n defineHeadingSpec(),\n defineHeadingInputRule(),\n defineHeadingKeymap(),\n defineHeadingCommands(),\n )\n}\n"],"mappings":";;;;;;AAkBA,SAAgB,wBAAkD;AAChE,QAAO,eAAe;EACpB,aAAa,UAAyB;AACpC,UAAO,aAAa;IAAE,MAAM;IAAW;IAAO,CAAC;;EAEjD,gBAAgB,UAAyB;AACvC,UAAO,WAAW;IAAE,MAAM;IAAW;IAAO,CAAC;;EAE/C,gBAAgB,UAAyB;AACvC,UAAO,WAAW;IAAE,MAAM;IAAW;IAAO,CAAC;;EAEhD,CAAC;;;;;;;;;;ACjBJ,SAAgB,yBAAyC;AACvD,QAAO,yBAAyB;EAC9B,OAAO;EACP,MAAM;EACN,QAAQ,UAAU;AAEhB,UAAO,EAAE,OADa,MAAM,IAAI,UAAU,GAC1B;;EAEnB,CAAC;;;;ACjBJ,SAAS,wBAAwB,OAAwB;AACvD,QAAO,kBAAkB,WAAW;EAAE,MAAM;EAAW,OAAO,EAAE,OAAO;EAAE,CAAC,CAAC;;;;;;AAO7E,MAAM,yBAAkC,OAAO,UAAU,SAAS;AAEhE,KADa,eAAe,OAAO,KAAK,EAC9B,OAAO,KAAK,SAAS,UAC7B,QAAO,gBAAgB,CAAC,OAAO,UAAU,KAAK;AAEhD,QAAO;;;;;AAMT,SAAgB,sBAAsC;AACpD,QAAO,aAAa;EAClB,aAAa,wBAAwB,EAAE;EACvC,aAAa,wBAAwB,EAAE;EACvC,aAAa,wBAAwB,EAAE;EACvC,aAAa,wBAAwB,EAAE;EACvC,aAAa,wBAAwB,EAAE;EACvC,aAAa,wBAAwB,EAAE;EACvC,aAAa;EACd,CAAC;;;;;;;ACfJ,SAAgB,oBAA0C;AACxD,QAAO,eAAe;EACpB,MAAM;EACN,OAAO,EAAE,OAAO;GAAE,SAAS;GAAG,UAAU;GAAU,EAAE;EACpD,SAAS;EACT,OAAO;EACP,UAAU;EACV,UAAU;GACR;IAAE,KAAK;IAAM,OAAO,EAAE,OAAO,GAAG;IAAE;GAClC;IAAE,KAAK;IAAM,OAAO,EAAE,OAAO,GAAG;IAAE;GAClC;IAAE,KAAK;IAAM,OAAO,EAAE,OAAO,GAAG;IAAE;GAClC;IAAE,KAAK;IAAM,OAAO,EAAE,OAAO,GAAG;IAAE;GAClC;IAAE,KAAK;IAAM,OAAO,EAAE,OAAO,GAAG;IAAE;GAClC;IAAE,KAAK;IAAM,OAAO,EAAE,OAAO,GAAG;IAAE;GACnC;EACD,MAAM,MAAM;AACV,UAAO,CAAC,IAAI,KAAK,MAAM,SAAS,EAAE;;EAErC,CAAC;;;;;;;ACjBJ,SAAgB,gBAAkC;AAChD,QAAO,MACL,mBAAmB,EACnB,wBAAwB,EACxB,qBAAqB,EACrB,uBAAuB,CACxB"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"prosekit-extensions-horizontal-rule.d.ts","names":[],"sources":["../src/horizontal-rule/horizontal-rule-commands.ts","../src/horizontal-rule/horizontal-rule-input-rule.ts","../src/horizontal-rule/horizontal-rule-spec.ts","../src/horizontal-rule/horizontal-rule.ts"],"mappings":";;;;;KAIY,+BAAA,GAAkC,SAAA;EAC5C,QAAA;IACE,oBAAA;EAAA;AAAA;;;;iBAoBY,oBAAA,CAAA,GAAwB,OAAA;AAAA,iBAIxB,4BAAA,CAAA,GAAgC,+BAAA;;;;;;iBCtBhC,6BAAA,CAAA,GAAiC,cAAA;;;KCLrC,2BAAA,GAA8B,SAAA;EACxC,KAAA;IACE,cAAA,EAAgB,KAAA;EAAA;AAAA;AAAA,iBAIJ,wBAAA,CAAA,GAA4B,2BAAA;;;KCHhC,uBAAA,GAA0B,KAAA,EACnC,2BAAA,EAA6B,+BAAA;;;;iBAMhB,oBAAA,CAAA,GAAwB,uBAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"prosekit-extensions-horizontal-rule.js","names":[],"sources":["../src/horizontal-rule/horizontal-rule-commands.ts","../src/horizontal-rule/horizontal-rule-input-rule.ts","../src/horizontal-rule/horizontal-rule-spec.ts","../src/horizontal-rule/horizontal-rule.ts"],"sourcesContent":["import { defineCommands, getNodeType, type Extension } from '@prosekit/core'\nimport { Fragment, Slice } from '@prosekit/pm/model'\nimport type { Command } from '@prosekit/pm/state'\n\nexport type HorizontalRuleCommandsExtension = Extension<{\n Commands: {\n insertHorizontalRule: []\n }\n}>\n\nconst insertHorizontalRuleCommand: Command = (state, dispatch): boolean => {\n if (!dispatch) return true\n\n const { schema, tr } = state\n const type = getNodeType(schema, 'horizontalRule')\n const node = type.createChecked()\n const pos = tr.selection.anchor\n const slice = new Slice(Fragment.from(node), 0, 0)\n tr.replaceRange(pos, pos, slice).scrollIntoView()\n dispatch(tr)\n return true\n}\n\n/**\n * Returns a command that inserts a horizontal rule at the current selection.\n */\nexport function insertHorizontalRule(): Command {\n return insertHorizontalRuleCommand\n}\n\nexport function defineHorizontalRuleCommands(): HorizontalRuleCommandsExtension {\n return defineCommands({ insertHorizontalRule })\n}\n","import { getNodeType, union, type PlainExtension } from '@prosekit/core'\nimport { InputRule } from '@prosekit/pm/inputrules'\n\nimport { defineInputRule } from '../input-rule/index.ts'\n\n/**\n * @public\n */\nexport function defineHorizontalRuleInputRule(): PlainExtension {\n return union(\n defineInputRule(\n new InputRule(/^---$/, (state, match, start, end) => {\n const { schema } = state\n const { tr } = state\n const type = getNodeType(schema, 'horizontalRule')\n const node = type.createChecked()\n tr.delete(start, end).insert(start - 1, node)\n return tr.scrollIntoView()\n }),\n ),\n )\n}\n","import { defineNodeSpec, type Extension } from '@prosekit/core'\nimport type { Attrs } from '@prosekit/pm/model'\n\nexport type HorizontalRuleSpecExtension = Extension<{\n Nodes: {\n horizontalRule: Attrs\n }\n}>\n\nexport function defineHorizontalRuleSpec(): HorizontalRuleSpecExtension {\n return defineNodeSpec({\n name: 'horizontalRule',\n group: 'block',\n parseDOM: [{ tag: 'hr' }],\n // Wrap the `<hr>` in a `<div>` so that we can make it taller and easier to click.\n toDOM: () => ['div', { class: 'prosekit-horizontal-rule' }, ['hr']],\n })\n}\n","import { union, type Union } from '@prosekit/core'\n\nimport { defineHorizontalRuleCommands, type HorizontalRuleCommandsExtension } from './horizontal-rule-commands.ts'\nimport { defineHorizontalRuleInputRule } from './horizontal-rule-input-rule.ts'\nimport { defineHorizontalRuleSpec, type HorizontalRuleSpecExtension } from './horizontal-rule-spec.ts'\n\nexport type HorizontalRuleExtension = Union<\n [HorizontalRuleSpecExtension, HorizontalRuleCommandsExtension]\n>\n\n/**\n * @public\n */\nexport function defineHorizontalRule(): HorizontalRuleExtension {\n return union(\n defineHorizontalRuleSpec(),\n defineHorizontalRuleInputRule(),\n defineHorizontalRuleCommands(),\n )\n}\n"],"mappings":";;;;;AAUA,MAAM,+BAAwC,OAAO,aAAsB;AACzE,KAAI,CAAC,SAAU,QAAO;CAEtB,MAAM,EAAE,QAAQ,OAAO;CAEvB,MAAM,OADO,YAAY,QAAQ,iBAAiB,CAChC,eAAe;CACjC,MAAM,MAAM,GAAG,UAAU;CACzB,MAAM,QAAQ,IAAI,MAAM,SAAS,KAAK,KAAK,EAAE,GAAG,EAAE;AAClD,IAAG,aAAa,KAAK,KAAK,MAAM,CAAC,gBAAgB;AACjD,UAAS,GAAG;AACZ,QAAO;;;;;AAMT,SAAgB,uBAAgC;AAC9C,QAAO;;AAGT,SAAgB,+BAAgE;AAC9E,QAAO,eAAe,EAAE,sBAAsB,CAAC;;;;;;;ACvBjD,SAAgB,gCAAgD;AAC9D,QAAO,MACL,gBACE,IAAI,UAAU,UAAU,OAAO,OAAO,OAAO,QAAQ;EACnD,MAAM,EAAE,WAAW;EACnB,MAAM,EAAE,OAAO;EAEf,MAAM,OADO,YAAY,QAAQ,iBAAiB,CAChC,eAAe;AACjC,KAAG,OAAO,OAAO,IAAI,CAAC,OAAO,QAAQ,GAAG,KAAK;AAC7C,SAAO,GAAG,gBAAgB;GAC1B,CACH,CACF;;;;ACXH,SAAgB,2BAAwD;AACtE,QAAO,eAAe;EACpB,MAAM;EACN,OAAO;EACP,UAAU,CAAC,EAAE,KAAK,MAAM,CAAC;EAEzB,aAAa;GAAC;GAAO,EAAE,OAAO,4BAA4B;GAAE,CAAC,KAAK;GAAC;EACpE,CAAC;;;;;;;ACHJ,SAAgB,uBAAgD;AAC9D,QAAO,MACL,0BAA0B,EAC1B,+BAA+B,EAC/B,8BAA8B,CAC/B"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"prosekit-extensions-image.d.ts","names":[],"sources":["../src/image/image-commands/upload-image.ts","../src/image/image-spec.ts","../src/image/image-commands.ts","../src/image/image-commands/insert-image.ts","../src/image/image-upload-handler.ts","../src/image/image.ts"],"mappings":";;;;;;;;;AAYA;;UAAiB,kBAAA;EAKL;;;;EAAV,QAAA,EAAU,QAAA;EAAV;;;EAIA,IAAA,EAAM,IAAA;EAKN;;;;EAAA,GAAA;EAWiC;AAQnC;;;;;EAZE,OAAA;EAoBA;;;EAhBA,OAAA,GAAU,uBAAA;AAAA;AA4BZ;;;;;AAAA,UApBiB,8BAAA;EA8BU;;;EA1BzB,IAAA,EAAM,IAAA;EA6BN;;;EAzBA,KAAA;EA4BsB;;;EAxBtB,UAAA,EAAY,UAAA;AAAA;;;;;;KAQF,uBAAA,IAA2B,OAAA,EAAS,8BAAA;;;;;;;AAkFhD;;iBAxEgB,WAAA,CAAA;EACd,QAAA;EACA,IAAA;EACA,GAAA;EACA,OAAA;EACA;AAAA,GACC,kBAAA,GAAqB,OAAA;;;;;;iBAkER,eAAA,CACd,IAAA,EAAM,UAAA,EACN,MAAA,UACA,MAAA;;;;;;UCjJe,UAAA;EACf,GAAA;EACA,KAAA;EACA,MAAA;AAAA;;;;KAMU,kBAAA,GAAqB,SAAA;EAC/B,KAAA;IACE,KAAA,EAAO,UAAA;EAAA;AAAA;;;;iBAOK,eAAA,CAAA,GAAmB,kBAAA;;;;;;KCdvB,sBAAA,GAAyB,SAAA;EACnC,QAAA;IACE,WAAA,GAAc,KAAA,GAAQ,UAAA;IACtB,WAAA,GAAc,OAAA,EAAS,kBAAA;EAAA;AAAA;;;;iBAOX,mBAAA,CAAA,GAAuB,sBAAA;;;;;;;AFPvC;;iBGDgB,WAAA,CAAY,KAAA,GAAQ,UAAA,GAAa,OAAA;;;;;;KCMrC,sBAAA,IAA0B,OAAA,EAAS,uBAAA;;;;KAKnC,qBAAA,IAAyB,OAAA,EAAS,sBAAA;;;;UAK7B,yBAAA;EJVL;;;;EIeV,QAAA,EAAU,QAAA;EJKV;;;;EIAA,QAAA,GAAW,sBAAA;EJQkC;;;;EIH7C,OAAA,GAAU,qBAAA;EJWV;;;;EINA,OAAA,GAAU,uBAAA;AAAA;;;;;AJ4BZ;;iBIVgB,wBAAA,CAAA;EACd,QAAA;EACA,QAAA;EACA,OAAA;EACA;AAAA,GACC,yBAAA,GAA4B,cAAA;;;;;;KC9DnB,cAAA,GAAiB,KAAA,EAAO,kBAAA,EAAoB,sBAAA;;;;iBAKxC,WAAA,CAAA,GAAe,cAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"prosekit-extensions-image.js","names":[],"sources":["../src/image/image-commands/insert-image.ts","../src/image/image-commands/upload-image.ts","../src/image/image-commands.ts","../src/image/image-spec.ts","../src/image/image-upload-handler.ts","../src/image/image.ts"],"sourcesContent":["import { insertNode } from '@prosekit/core'\nimport type { Command } from '@prosekit/pm/state'\n\nimport type { ImageAttrs } from '../image-spec.ts'\n\n/**\n * Returns a command that inserts an image node with the given attributes at the\n * current selection position.\n *\n * @public\n */\nexport function insertImage(attrs?: ImageAttrs): Command {\n return insertNode({ type: 'image', attrs })\n}\n","import { insertNode, ProseKitError } from '@prosekit/core'\nimport type { Command, EditorState, Transaction } from '@prosekit/pm/state'\nimport type { EditorView } from '@prosekit/pm/view'\n\nimport { UploadTask, type Uploader } from '../../file/index.ts'\nimport type { ImageAttrs } from '../image-spec.ts'\n\n/**\n * Options for {@link uploadImage}.\n *\n * @public\n */\nexport interface UploadImageOptions {\n /**\n * The uploader used to upload the file. It should return a promise that\n * resolves to the URL of the uploaded image.\n */\n uploader: Uploader<string>\n /**\n * The file that will be uploaded.\n */\n file: File\n /**\n * The position where the image should be inserted. If not provided, the\n * image is inserted at the current selection.\n */\n pos?: number\n /**\n * If the image should replace the existing image at the given position. This\n * is only used if `pos` is provided.\n *\n * @default false\n */\n replace?: boolean\n /**\n * A handler to be called when an error occurs during the upload.\n */\n onError?: ImageUploadErrorHandler\n}\n\n/**\n * Options for the {@link ImageUploadErrorHandler} callback.\n *\n * @public\n */\nexport interface ImageUploadErrorHandlerOptions {\n /**\n * The file that was uploaded.\n */\n file: File\n /**\n * The error that occurred during the upload.\n */\n error: unknown\n /**\n * The upload task that was used to upload the file.\n */\n uploadTask: UploadTask<string>\n}\n\n/**\n * A handler to be called when an error occurs during the upload.\n *\n * @public\n */\nexport type ImageUploadErrorHandler = (options: ImageUploadErrorHandlerOptions) => void\n\n/**\n * Returns a command that uploads an image file and inserts an image node with a\n * temporary URL which is replaced once the upload completes.\n *\n * @param options\n *\n * @public\n */\nexport function uploadImage({\n uploader,\n file,\n pos,\n replace = false,\n onError,\n}: UploadImageOptions): Command {\n return (state, dispatch, view) => {\n const uploadTask = new UploadTask({ file, uploader })\n const objectURL = uploadTask.objectURL\n\n uploadTask.finished\n .then((resultURL) => {\n if (view && view.isDestroyed) {\n return\n } else if (typeof resultURL !== 'string') {\n const error = new ProseKitError(\n `Unexpected upload result. Expected a string but got ${typeof resultURL}`,\n )\n onError?.({ file, error, uploadTask })\n } else if (!view) {\n const error = new ProseKitError(\n 'View must be available to replace the image URL',\n )\n onError?.({ file, error, uploadTask })\n } else {\n replaceImageURL(view, objectURL, resultURL)\n UploadTask.delete(objectURL)\n }\n })\n .catch((error) => {\n onError?.({ file, error, uploadTask })\n })\n\n if (replace && pos != null) {\n if (replaceExistingImageURL(state, pos, objectURL, dispatch)) {\n return true\n }\n }\n\n const attrs: ImageAttrs = { src: objectURL }\n return insertNode({ type: 'image', attrs, pos })(state, dispatch, view)\n }\n}\n\nfunction replaceExistingImageURL(\n state: EditorState,\n pos: number,\n imageURL: string,\n dispatch?: (tr: Transaction) => void,\n): boolean {\n const node = state.doc.nodeAt(pos)\n if (!node || node.type.name !== 'image') {\n return false\n }\n const attrs = node.attrs as ImageAttrs\n if (attrs.src === imageURL) {\n return true\n }\n if (dispatch) {\n const tr = state.tr\n tr.setNodeAttribute(pos, 'src', imageURL)\n dispatch(tr)\n }\n return true\n}\n\n/**\n * Replaces the temporary image URL with the final uploaded URL.\n *\n * @internal\n */\nexport function replaceImageURL(\n view: EditorView,\n oldURL: string,\n newURL: string,\n): void {\n const positions: number[] = []\n view.state.doc.descendants((node, pos) => {\n if (node.type.name === 'image') {\n const attrs = node.attrs as ImageAttrs\n if (attrs.src === oldURL) {\n positions.push(pos)\n }\n }\n })\n\n if (positions.length === 0) {\n return\n }\n\n const tr = view.state.tr\n for (const pos of positions) {\n tr.setNodeAttribute(pos, 'src', newURL)\n }\n view.dispatch(tr)\n}\n","import { defineCommands, type Extension } from '@prosekit/core'\n\nimport { insertImage } from './image-commands/insert-image.ts'\nimport { uploadImage, type UploadImageOptions } from './image-commands/upload-image.ts'\nimport type { ImageAttrs } from './image-spec.ts'\n\n/**\n * @internal\n */\nexport type ImageCommandsExtension = Extension<{\n Commands: {\n insertImage: [attrs?: ImageAttrs]\n uploadImage: [options: UploadImageOptions]\n }\n}>\n\n/**\n * @internal\n */\nexport function defineImageCommands(): ImageCommandsExtension {\n return defineCommands({\n insertImage,\n uploadImage,\n })\n}\n","import { defineNodeSpec, type Extension } from '@prosekit/core'\n\n/**\n * @public\n */\nexport interface ImageAttrs {\n src?: string | null\n width?: number | null\n height?: number | null\n}\n\n/**\n * @internal\n */\nexport type ImageSpecExtension = Extension<{\n Nodes: {\n image: ImageAttrs\n }\n}>\n\n/**\n * @internal\n */\nexport function defineImageSpec(): ImageSpecExtension {\n return defineNodeSpec({\n name: 'image',\n attrs: {\n src: { default: null, validate: 'string|null' },\n width: { default: null, validate: 'number|null' },\n height: { default: null, validate: 'number|null' },\n },\n group: 'block',\n defining: true,\n draggable: true,\n parseDOM: [\n {\n tag: 'img[src]',\n getAttrs: (element): ImageAttrs => {\n if (typeof element === 'string') {\n return { src: null }\n }\n\n const src = element.getAttribute('src') || null\n\n let width: number | null = null\n let height: number | null = null\n\n const rect = element.getBoundingClientRect()\n if (rect.width > 0 && rect.height > 0) {\n width = rect.width\n height = rect.height\n } else if (\n element instanceof HTMLImageElement\n && element.naturalWidth > 0\n && element.naturalHeight > 0\n ) {\n width = element.naturalWidth\n height = element.naturalHeight\n }\n return { src, width, height }\n },\n },\n ],\n toDOM(node) {\n const attrs = node.attrs as ImageAttrs\n return ['img', attrs]\n },\n })\n}\n","import { union, type PlainExtension } from '@prosekit/core'\n\nimport {\n defineFileDropHandler,\n defineFilePasteHandler,\n type FileDropHandler,\n type FileDropHandlerOptions,\n type FilePasteHandler,\n type FilePasteHandlerOptions,\n type Uploader,\n} from '../file/index.ts'\n\nimport { uploadImage, type ImageUploadErrorHandler } from './image-commands/upload-image.ts'\n\n/**\n * A predicate to determine if the pasted file should be uploaded and inserted as an image.\n */\nexport type ImageCanPastePredicate = (options: FilePasteHandlerOptions) => boolean\n\n/**\n * A predicate to determine if the dropped file should be uploaded and inserted as an image.\n */\nexport type ImageCanDropPredicate = (options: FileDropHandlerOptions) => boolean\n\n/**\n * A handler to be called when an error occurs during the upload.\n */\nexport interface ImageUploadHandlerOptions {\n /**\n * The uploader used to upload the file. It should return a promise that\n * resolves to the URL of the uploaded image.\n */\n uploader: Uploader<string>\n /**\n * A predicate to determine if the pasted file should be uploaded and inserted as an image.\n * If not provided, it defaults to only allowing paste of files with a content type starting with `image/`.\n */\n canPaste?: ImageCanPastePredicate\n /**\n * A predicate to determine if the dropped file should be uploaded and inserted as an image.\n * If not provided, it defaults to only allowing drop of files with a content type starting with `image/`.\n */\n canDrop?: ImageCanDropPredicate\n /**\n * A handler to be called when an error occurs during the upload.\n * If not provided, it defaults to logging the error to the console.\n */\n onError?: ImageUploadErrorHandler\n}\n\nfunction defaultCanUpload({ file }: { file: File }): boolean {\n // Only handle image files by default\n return file.type.startsWith('image/')\n}\n\nconst defaultOnError: ImageUploadErrorHandler = ({ error }) => {\n console.error('[prosekit] Failed to upload image:', error)\n}\n\n/**\n * Returns an extension that handles image file uploads when pasting or dropping\n * images into the editor.\n *\n * @param options\n */\nexport function defineImageUploadHandler({\n uploader,\n canPaste = defaultCanUpload,\n canDrop = defaultCanUpload,\n onError = defaultOnError,\n}: ImageUploadHandlerOptions): PlainExtension {\n const handlePaste: FilePasteHandler = (options) => {\n if (!canPaste(options)) return false\n const { view, file } = options\n const command = uploadImage({ uploader, file, onError })\n return command(view.state, view.dispatch, view)\n }\n\n const handleDrop: FileDropHandler = (options) => {\n if (!canDrop(options)) return false\n const { view, file, pos } = options\n const command = uploadImage({ uploader, file, onError, pos })\n return command(view.state, view.dispatch, view)\n }\n\n return union(\n defineFilePasteHandler(handlePaste),\n defineFileDropHandler(handleDrop),\n )\n}\n","import { union, type Union } from '@prosekit/core'\n\nimport { defineImageCommands, type ImageCommandsExtension } from './image-commands.ts'\nimport { defineImageSpec, type ImageSpecExtension } from './image-spec.ts'\n\n/**\n * @internal\n */\nexport type ImageExtension = Union<[ImageSpecExtension, ImageCommandsExtension]>\n\n/**\n * @public\n */\nexport function defineImage(): ImageExtension {\n return union(defineImageSpec(), defineImageCommands())\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"prosekit-extensions-input-rule.d.ts","names":[],"sources":["../src/input-rule/index.ts"],"mappings":";;;;;;;AAsBA;;;;;iBAAgB,eAAA,CAAgB,IAAA,EAAM,SAAA,GAAY,cAAA;;;;AASlD;;UAAiB,oBAAA;EAMR;;;;;EAAP,KAAA,EAAO,MAAA;EAUmD;;;EAL1D,IAAA,WAAe,QAAA;EAAA;;;EAKf,KAAA,GAAQ,KAAA,YAAiB,KAAA,EAAO,gBAAA,KAAqB,KAAA;EAA5B;;;;;EAOzB,UAAA;AAAA;;;;iBAMc,mBAAA,CAAA;EACd,KAAA;EACA,IAAA;EACA,KAAA;EACA;AAAA,GACC,oBAAA,GAAuB,SAAA;;;;;;;iBAqDV,mBAAA,CACd,OAAA,EAAS,oBAAA,GACR,cAAA;;;;;;;;;;;iBAca,wBAAA,CAAA;EACd,KAAA;EACA,IAAA;EACA;AAAA;EAnBiC;;;;;EA0BjC,KAAA,EAAO,MAAA;EAxBQ;;AAcjB;EAeE,IAAA,WAAe,QAAA;;;;EAKf,KAAA,GAAQ,KAAA,YAAiB,KAAA,EAAO,gBAAA,KAAqB,KAAA;AAAA,IACnD,cAAA;;;;;;;;;;;iBAiBY,uBAAA,CAAA;EACd,KAAA;EACA,IAAA;EACA,KAAA;EACA;AAAA;EAvCA;;;;;EA8CA,KAAA,EAAO,MAAA;EA7BP;;;EAkCA,IAAA,WAAe,QAAA;EAlCsC;;;EAuCrD,KAAA,GAAQ,KAAA,YAAiB,KAAA,EAAO,gBAAA,KAAqB,KAAA;EArBvC;;;;;;;;EA+Bd,IAAA,IAAQ,KAAA,EAAO,gBAAA,EAAkB,IAAA,EAAM,eAAA;AAAA,IACrC,cAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"prosekit-extensions-input-rule.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 { InputRule, inputRules, textblockTypeInputRule, wrappingInputRule } from '@prosekit/pm/inputrules'\nimport type { Attrs, MarkType, NodeType, ProseMirrorNode, Schema } 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":";;;;;;;;;;AAsBA,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 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"prosekit-extensions-italic.d.ts","names":[],"sources":["../src/italic/italic-commands.ts","../src/italic/italic-input-rule.ts","../src/italic/italic-keymap.ts","../src/italic/italic-spec.ts","../src/italic/italic.ts"],"mappings":";;;;;;;KAKY,uBAAA,GAA0B,SAAA;EACpC,QAAA;IACE,YAAA;EAAA;AAAA;;;;iBAOY,oBAAA,CAAA,GAAwB,uBAAA;;;;;;iBCPxB,qBAAA,CAAA,GAAyB,cAAA;;;;;;iBCFzB,kBAAA,CAAA,GAAsB,cAAA;;;;;AFAtC;KGCY,mBAAA,GAAsB,SAAA;EAChC,KAAA;IACE,MAAA,EAAQ,KAAA;EAAA;AAAA;;;;iBAOI,gBAAA,CAAA,GAAoB,mBAAA;;;;AHVpC;;KIKY,eAAA,GAAkB,KAAA,EAC3B,mBAAA,EAAqB,uBAAA;;;;iBAMR,YAAA,CAAA,GAAgB,eAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"prosekit-extensions-italic.js","names":[],"sources":["../src/italic/italic-commands.ts","../src/italic/italic-input-rule.ts","../src/italic/italic-keymap.ts","../src/italic/italic-spec.ts","../src/italic/italic.ts"],"sourcesContent":["import { defineCommands, toggleMark, type Extension } from '@prosekit/core'\n\n/**\n * @internal\n */\nexport type ItalicCommandsExtension = Extension<{\n Commands: {\n toggleItalic: []\n }\n}>\n\n/**\n * @internal\n */\nexport function defineItalicCommands(): ItalicCommandsExtension {\n return defineCommands({\n toggleItalic: () => toggleMark({ type: 'italic' }),\n })\n}\n","import { canUseRegexLookbehind, type PlainExtension } from '@prosekit/core'\n\nimport { defineMarkInputRule } from '../input-rule/index.ts'\n\n/**\n * @internal\n */\nexport function defineItalicInputRule(): PlainExtension {\n return defineMarkInputRule({\n regex: canUseRegexLookbehind()\n ? /(?<=\\s|^)\\*([^\\s*]|[^\\s*][^*]*[^\\s*])\\*$/\n : /\\*([^\\s*]|[^\\s*][^*]*[^\\s*])\\*$/,\n type: 'italic',\n })\n}\n","import { defineKeymap, toggleMark, type PlainExtension } from '@prosekit/core'\n\n/**\n * @internal\n */\nexport function defineItalicKeymap(): PlainExtension {\n return defineKeymap({\n 'Mod-i': toggleMark({ type: 'italic' }),\n })\n}\n","import { defineMarkSpec, type Extension } from '@prosekit/core'\nimport type { Attrs } from '@prosekit/pm/model'\n\n/**\n * @internal\n */\nexport type ItalicSpecExtension = Extension<{\n Marks: {\n italic: Attrs\n }\n}>\n\n/**\n * @internal\n */\nexport function defineItalicSpec(): ItalicSpecExtension {\n return defineMarkSpec({\n name: 'italic',\n parseDOM: [\n { tag: 'i' },\n { tag: 'em' },\n { style: 'font-style=italic' },\n {\n style: 'font-style=normal',\n clearMark: (m) => m.type.name === 'italic',\n },\n ],\n toDOM() {\n return ['em', 0]\n },\n })\n}\n","import { union, type Union } from '@prosekit/core'\n\nimport { defineItalicCommands, type ItalicCommandsExtension } from './italic-commands.ts'\nimport { defineItalicInputRule } from './italic-input-rule.ts'\nimport { defineItalicKeymap } from './italic-keymap.ts'\nimport { defineItalicSpec, type ItalicSpecExtension } from './italic-spec.ts'\n\n/**\n * @internal\n */\nexport type ItalicExtension = Union<\n [ItalicSpecExtension, ItalicCommandsExtension]\n>\n\n/**\n * @public\n */\nexport function defineItalic(): ItalicExtension {\n return union(\n defineItalicSpec(),\n defineItalicCommands(),\n defineItalicKeymap(),\n defineItalicInputRule(),\n )\n}\n"],"mappings":";;;;;;AAcA,SAAgB,uBAAgD;AAC9D,QAAO,eAAe,EACpB,oBAAoB,WAAW,EAAE,MAAM,UAAU,CAAC,EACnD,CAAC;;;;;;;ACVJ,SAAgB,wBAAwC;AACtD,QAAO,oBAAoB;EACzB,OAAO,uBAAuB,GAC1B,6CACA;EACJ,MAAM;EACP,CAAC;;;;;;;ACRJ,SAAgB,qBAAqC;AACnD,QAAO,aAAa,EAClB,SAAS,WAAW,EAAE,MAAM,UAAU,CAAC,EACxC,CAAC;;;;;;;ACOJ,SAAgB,mBAAwC;AACtD,QAAO,eAAe;EACpB,MAAM;EACN,UAAU;GACR,EAAE,KAAK,KAAK;GACZ,EAAE,KAAK,MAAM;GACb,EAAE,OAAO,qBAAqB;GAC9B;IACE,OAAO;IACP,YAAY,MAAM,EAAE,KAAK,SAAS;IACnC;GACF;EACD,QAAQ;AACN,UAAO,CAAC,MAAM,EAAE;;EAEnB,CAAC;;;;;;;ACbJ,SAAgB,eAAgC;AAC9C,QAAO,MACL,kBAAkB,EAClB,sBAAsB,EACtB,oBAAoB,EACpB,uBAAuB,CACxB"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"prosekit-extensions-link.d.ts","names":[],"sources":["../src/link/link-paste-rule.ts","../src/link/link-types.ts","../src/link/index.ts"],"mappings":";;;;;AAUA;iBAAgB,mBAAA,CAAA,GAAuB,cAAA;;;;;;UCPtB,SAAA;EACf,IAAA;EACA,MAAA;EACA,GAAA;AAAA;;;;;;KCsBU,iBAAA,GAAoB,SAAA;EAC9B,KAAA;IACE,IAAA,EAAM,SAAA;EAAA;AAAA;;;;iBAOM,cAAA,CAAA,GAAkB,iBAAA;;;;KA+BtB,qBAAA,GAAwB,SAAA;EAClC,QAAA;IACE,OAAA,GAAU,KAAA,EAAO,SAAA;IACjB,UAAA;IACA,UAAA,GAAa,KAAA,EAAO,SAAA;IACpB,UAAA;EAAA;AAAA;AAAA,iBAIY,kBAAA,CAAA,GAAsB,qBAAA;;;;;AAxCtC;iBAsDgB,mBAAA,CAAA,GAAuB,cAAA;;;;AAvBvC;;iBAwCgB,mBAAA,CAAA,GAAuB,cAAA;;;;;;iBAmBvB,kBAAA,CAAA,GAAsB,cAAA;;;;KAW1B,aAAA,GAAgB,KAAA,EAAO,iBAAA,EAAmB,qBAAA;;;;iBAKtC,UAAA,CAAA,GAAc,aAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"prosekit-extensions-link.js","names":[],"sources":["../src/link/link-regex.ts","../src/link/link-paste-rule.ts","../src/link/index.ts"],"sourcesContent":["/* eslint-disable unicorn/prefer-string-raw -- Don't use String.raw here for better bundler minification */\n\n// All valid alpha TLDs.\n// Data source: https://data.iana.org/TLD/tlds-alpha-by-domain.txt\nconst TLD_RE_PATTERN =\n 'a(?:a(?:a|rp)|b(?:arth|b(?:ott|vie)?|c|le|ogado|udhabi)|c(?:ademy|c(?:enture|ountants?)|o|tor)?|d(?:s|ult)?|e(?:g|ro|tna)?|f(?:l|rica)?|g(?:akhan|ency)?|i(?:g|r(?:bus|force|tel))?|kdn|l(?:faromeo|i(?:baba|pay)|l(?:finanz|state|y)|s(?:ace|tom))?|m(?:azon|e(?:rican(?:express|family)|x)|fam|ica|sterdam)?|n(?:alytics|droid|quan|z)|ol?|p(?:artments|p(?:le)?)|q(?:uarelle)?|r(?:a(?:b|mco)|chi|my|pa|te?)?|s(?:da|ia|sociates)?|t(?:hleta|torney)?|u(?:ction|di(?:ble|o)?|spost|t(?:hor|os?))?|vianca|ws?|xa?|z(?:ure)?)|b(?:a(?:by|idu|n(?:a(?:mex|narepublic)|d|k)|r(?:c(?:elona|lay(?:card|s))|efoot|gains)?|s(?:eball|ketball)|uhaus|yern)?|b(?:c|t|va)?|c[gn]|d|e(?:a(?:ts|uty)|er|ntley|rlin|st(?:buy)?|t)?|f|g|h(?:arti)?|i(?:ble|d|ke|ngo?|o|z)?|j|l(?:ack(?:friday)?|o(?:ckbuster|g|omberg)|ue)|m[sw]?|n(?:pparibas)?|o(?:ats|ehringer|fa|m|nd|o(?:k(?:ing)?)?|s(?:ch|t(?:ik|on))|t|utique|x)?|r(?:adesco|idgestone|o(?:adway|ker|ther)|ussels)?|s|t|u(?:ild(?:ers)?|siness|y|zz)|v|w|y|zh?)|c(?:a(?:b|fe|l(?:l|vinklein)?|m(?:era|p)?|non|p(?:etown|ital(?:one)?)|r(?:avan|ds|e(?:ers?)?|s)?|s(?:a|e|h|ino)|t(?:ering|holic)?)?|b(?:a|n|re|s)|c|d|e(?:nter|o|rn)|f[ad]?|g|h(?:a(?:n(?:el|nel)|rity|se|t)|eap|intai|r(?:istmas|ome)|urch)?|i(?:priani|rcle|sco|t(?:adel|ic?|y(?:eats)?))?|k|l(?:aims|eaning|i(?:ck|ni(?:c|que))|o(?:thing|ud)|ub(?:med)?)?|m|n|o(?:ach|des|ffee|l(?:lege|ogne)|m(?:cast|m(?:bank|unity)|p(?:a(?:ny|re)|uter)|sec)?|n(?:dos|s(?:truction|ulting)|t(?:act|ractors))|o(?:king(?:channel)?|l|p)|rsica|u(?:ntry|pons?|rses))?|pa|r(?:edit(?:card|union)?|icket|own|s|uises?)?|u(?:isinella)?|v|w|x|y(?:mru|ou)?|z)|d(?:a(?:bur|d|nce|t(?:a|e|ing|sun)|y)|clk|ds|e(?:al(?:er|s)?|gree|l(?:ivery|l|oitte|ta)|mocrat|nt(?:al|ist)|si(?:gn)?|v)?|hl|i(?:amonds|et|gital|rect(?:ory)?|s(?:co(?:unt|ver)|h)|y)|j|k|m|np|o(?:c(?:s|tor)|g|mains|t|wnload)?|rive|tv|u(?:bai|nlop|pont|rban)|v(?:ag|r)|z)|e(?:a(?:rth|t)|co?|d(?:eka|u(?:cation)?)|e|g|m(?:ail|erck)|n(?:ergy|gineer(?:ing)?|terprises)|pson|quipment|r(?:icsson|ni)?|s(?:q|tate)?|t(?:isalat)?|u(?:rovision|s)?|vents|x(?:change|p(?:ert|osed|ress)|traspace))|f(?:a(?:ge|i(?:l|rwinds|th)|mily|ns?|rm(?:ers)?|s(?:hion|t))|e(?:dex|edback|rr(?:ari|ero))|i(?:at|d(?:elity|o)|lm|na(?:l|nc(?:e|ial))|r(?:e(?:stone)?|mdale)|sh(?:ing)?|t(?:ness)?)?|j|k|l(?:i(?:ckr|ghts|r)|o(?:rist|wers)|y)|m|o(?:o(?:d(?:network)?|tball)?|r(?:d|ex|sale|um)|undation|x)?|r(?:e(?:e|senius)|l|o(?:gans|nt(?:door|ier)))?|tr|u(?:jitsu|nd?|rniture|tbol)|yi)|g(?:a(?:l(?:l(?:ery|o|up))?|mes?|p|rden|y)?|b(?:iz)?|dn?|e(?:a|nt(?:ing)?|orge)?|f|g(?:ee)?|h|i(?:fts?|v(?:es|ing))?|l(?:ass|e|ob(?:al|o))?|m(?:ail|bh|o|x)?|n|o(?:daddy|l(?:d(?:point)?|f)|o(?:dyear|g(?:le)?)?|p|t|v)|p|q|r(?:a(?:inger|phics|tis)|een|ipe|o(?:cery|up))?|s|t|u(?:ardian|cci|ge|i(?:de|tars)|ru)?|w|y)|h(?:a(?:ir|mburg|ngout|us)|bo|dfc(?:bank)?|e(?:alth(?:care)?|l(?:p|sinki)|r(?:e|mes))|gtv|i(?:phop|samitsu|tachi|v)|kt?|m|n|o(?:ckey|l(?:dings|iday)|me(?:depot|goods|s(?:ense)?)|nda|rse|s(?:pital|t(?:ing)?)|t(?:el(?:es|s)|mail)?|use|w)|r|sbc|t|u(?:ghes)?|y(?:att|undai))|i(?:bm|c(?:bc|e|u)|d|e(?:ee)?|fm|kano|l|m(?:amat|db|mo(?:bilien)?)?|n(?:c|dustries|f(?:initi|o)|g|k|s(?:titute|ur(?:ance|e))|t(?:ernational|uit)?|vestments)?|o|piranga|q|r(?:ish)?|s(?:maili|t(?:anbul)?)?|t(?:au|v)?)|j(?:a(?:guar|va)|cb|e(?:ep|tzt|welry)?|io|ll|mp?|nj|o(?:b(?:s|urg)|t|y)?|p(?:morgan|rs)?|u(?:egos|niper))|k(?:aufen|ddi|e(?:rry(?:hotels|logistics|properties))?|fh|g|h|i(?:a|ds|m|nd(?:er|le)|tchen|wi)?|m|n|o(?:eln|matsu|sher)|p(?:mg|n)?|r(?:d|ed)?|uokgroup|w|y(?:oto)?|z)|l(?:a(?:caixa|m(?:borghini|er)|n(?:c(?:aster|ia)|d(?:rover)?|xess)|salle|t(?:ino|robe)?|w(?:yer)?)?|b|c|ds|e(?:ase|clerc|frak|g(?:al|o)|xus)|gbt|i(?:dl|fe(?:insurance|style)?|ghting|ke|lly|m(?:ited|o)|n(?:coln|de|k)|psy|v(?:e|ing))?|k|l[cp]|o(?:ans?|c(?:ker|us)|l|ndon|tt[eo]|ve)|pl(?:financial)?|r|s|t(?:da?)?|u(?:ndbeck|x(?:e|ury))?|v|y)|m(?:a(?:cys|drid|i(?:f|son)|keup|n(?:agement|go)?|p|r(?:ket(?:ing|s)?|riott|shalls)|serati|ttel)?|ba|c(?:kinsey)?|d|e(?:d(?:ia)?|et|lbourne|m(?:e|orial)|nu?|rckmsd)?|g|h|i(?:ami|crosoft|l|n[it]|t(?:subishi)?)|k|l[bs]?|ma?|n|o(?:bi(?:le)?|da|e|i|m|n(?:ash|ey|ster)|r(?:mon|tgage)|scow|to(?:rcycles)?|v(?:ie)?)?|p|q|r|sd?|t[nr]?|u(?:s(?:eum|ic)|tual)?|v|w|x|y|z)|n(?:a(?:b|goya|me|tura|vy)?|ba|c|e(?:c|t(?:bank|flix|work)?|ustar|ws?|x(?:t(?:direct)?|us))?|fl?|go?|hk|i(?:co|k(?:e|on)|nja|ssa[ny])?|l|o(?:kia|rt(?:hwesternmutual|on)|w(?:ruz|tv)?)?|p|r[aw]?|tt|u|yc|z)|o(?:b(?:i|server)|ffice|kinawa|l(?:ayan(?:group)?|dnavy|lo)|m(?:ega)?|n(?:e|g|l(?:ine)?)|oo|pen|r(?:a(?:cle|nge)|g(?:anic)?|igins)|saka|t(?:suka|t)|vh)|p(?:a(?:ge|nasonic|r(?:is|s|t(?:ners|s|y))|ssagens|y)?|ccw|et?|f(?:izer)?|g|h(?:armacy|d|ilips|o(?:ne|to(?:graphy|s)?)|ysio)?|i(?:c(?:s|t(?:et|ures))|d|n[gk]?|oneer|zza)|k|l(?:a(?:ce|y(?:station)?)|u(?:mbing|s))?|m|nc?|o(?:hl|ker|litie|rn|st)|r(?:a(?:merica|xi)|ess|ime|o(?:d(?:uctions)?|f|gressive|mo|pert(?:ies|y)|tection)?|u(?:dential)?)?|s|t|ub|wc?|y)|q(?:a|pon|ue(?:bec|st))|r(?:a(?:cing|dio)|e(?:a(?:d|l(?:estate|t(?:or|y)))|cipes|d(?:stone|umbrella)?|hab|i(?:sen?|t)|liance|n(?:t(?:als)?)?|p(?:air|ort|ublican)|st(?:aurant)?|views?|xroth)?|i(?:c(?:h(?:ardli)?|oh)|l|o|p)|o(?:c(?:her|ks)|deo|gers|om)?|s(?:vp)?|u(?:gby|hr|n)?|we?|yukyu)|s(?:a(?:arland|fe(?:ty)?|kura|l(?:e|on)|ms(?:club|ung)|n(?:dvik(?:coromant)?|ofi)|p|rl|s|ve|xo)?|b[is]?|c(?:a|b|h(?:aeffler|midt|o(?:larships|ol)|ule|warz)|ience|ot)?|d|e(?:a(?:rch|t)|cur(?:e|ity)|ek|lect|ner|rvices|ven|w|xy?)?|fr|g|h(?:a(?:ngrila|rp|w)|ell|i(?:a|ksha)|o(?:es|p(?:ping)?|uji|w(?:time)?))?|i(?:lk|n(?:a|gles)|te)?|j|k(?:in?|y(?:pe)?)?|l(?:ing)?|m(?:art|ile)?|n(?:cf)?|o(?:c(?:cer|ial)|ft(?:bank|ware)|hu|l(?:ar|utions)|n[gy]|y)?|p(?:a(?:ce)?|o(?:rt|t))|rl?|s|t(?:a(?:da|ples|r|te(?:bank|farm))|c(?:group)?|o(?:ckholm|r(?:age|e))|ream|ud(?:io|y)|yle)?|u(?:cks|pp(?:l(?:ies|y)|ort)|r(?:f|gery)|zuki)?|v|w(?:atch|iss)|x|y(?:dney|stems)?|z)|t(?:a(?:b|ipei|lk|obao|rget|t(?:a(?:motors|r)|too)|xi?)|ci?|dk?|e(?:am|ch(?:nology)?|l|masek|nnis|va)|f|g|h(?:d|eat(?:er|re))?|i(?:aa|ckets|enda|ffany|ps|r(?:es|ol))|j(?:maxx|x)?|k(?:maxx)?|l|m(?:all)?|n|o(?:day|kyo|ols|p|ray|shiba|tal|urs|wn|y(?:ota|s))?|r(?:a(?:d(?:e|ing)|ining|vel(?:channel|ers(?:insurance)?)?)|ust|v)?|t|u(?:be|i|nes|shu)|vs?|w|z)|u(?:a|b(?:ank|s)|g|k|n(?:i(?:com|versity)|o)|ol|ps|s|y|z)|v(?:a(?:cations|n(?:a|guard))?|c|e(?:gas|ntures|r(?:isign|sicherung)|t)?|g|i(?:ajes|deo|g|king|llas|n|p|rgin|s(?:a|ion)|v[ao])?|laanderen|n|o(?:dka|l(?:kswagen|vo)|t(?:e|ing|o)|yage)|u(?:elos)?)|w(?:a(?:l(?:es|mart|ter)|ng(?:gou)?|tch(?:es)?)|e(?:ather(?:channel)?|b(?:cam|er|site)|d(?:ding)?|i(?:bo|r))|f|hoswho|i(?:en|ki|lliamhill|n(?:dows|e|ners)?)|me|o(?:lterskluwer|odside|r(?:ks?|ld)|w)|s|t[cf])|x(?:box|erox|finity|i(?:huan|n)|xx|yz)|y(?:a(?:chts|hoo|maxun|ndex)|e|o(?:dobashi|ga|kohama|u(?:tube)?)|t|un)|z(?:a(?:ppos|ra)?|ero|ip|m|one|uerich|w)'\n\n// Some common punctuations that can be used to stop a link\nconst PUNCTUATION_CHAR_PATTERN = '\\\\.\\\\,\\\\;\\\\!\\\\?'\n\nconst STOP_CHAR_PATTERN = '[' + PUNCTUATION_CHAR_PATTERN + ']'\n\nconst END_CHAR_PATTERN = '[^' + '\\\\s' + PUNCTUATION_CHAR_PATTERN + ']'\n\n// dprint-ignore\nconst LINK_RE_BASE_PATTERN = (\n // start of the link group\n '(' + \n '(?:' +\n // protocol identifier (optional)\n // short syntax // is allowed\n '(?:(?:https?:)?\\\\/\\\\/)?' +\n\n // host & domain names.\n '(?:' +\n '(?:' +\n '[a-z0-9\\\\u00a1-\\\\uffff]' +\n '[a-z0-9\\\\u00a1-\\\\uffff_-]{0,62}' +\n ')?' +\n '[a-z0-9\\\\u00a1-\\\\uffff]\\\\.' +\n ')+' +\n\n // TLD identifier name, must not end with dot\n '(?:' +\n TLD_RE_PATTERN +\n ')' +\n ')' +\n\n // port number (optional)\n '(?::\\\\d{2,5})?' +\n\n // sub path (optional)\n '(?:/' +\n '(?:' + \n '\\\\S*' +\n END_CHAR_PATTERN +\n ')?' +\n ')?' +\n\n // query string (optional)\n '(?:\\\\?' + \n '(?:' + \n '\\\\S*' +\n END_CHAR_PATTERN +\n ')' +\n ')?' +\n\n // fragment (optional)\n '(?:\\\\#' + \n '(?:' + \n '\\\\S*' +\n END_CHAR_PATTERN +\n ')?' +\n ')?' +\n\n // end of the link group\n ')'\n)\n\n// dprint-ignore\nconst LINK_ENTER_PATTERN = LINK_RE_BASE_PATTERN + STOP_CHAR_PATTERN + '?' + '$'\n// dprint-ignore\nconst LINK_INPUT_PATTERN = LINK_RE_BASE_PATTERN + STOP_CHAR_PATTERN + '?' + '\\\\s$'\n// dprint-ignore\nconst LINK_MARK_PATTERN = LINK_RE_BASE_PATTERN + '(?=' + STOP_CHAR_PATTERN + '|\\\\s|$)'\n\nexport const LINK_ENTER_RE: RegExp = new RegExp(LINK_ENTER_PATTERN, 'gi')\nexport const LINK_INPUT_RE: RegExp = new RegExp(LINK_INPUT_PATTERN, 'gi')\nexport const LINK_MARK_RE: RegExp = new RegExp(LINK_MARK_PATTERN, 'gi')\n","import type { PlainExtension } from '@prosekit/core'\n\nimport { defineMarkPasteRule } from '../paste-rule/index.ts'\n\nimport { LINK_MARK_RE } from './link-regex.ts'\nimport type { LinkAttrs } from './link-types.ts'\n\n/**\n * @internal\n */\nexport function defineLinkPasteRule(): PlainExtension {\n return defineMarkPasteRule({\n type: 'link',\n regex: LINK_MARK_RE,\n getAttrs: (match: RegExpExecArray): LinkAttrs | false => {\n if (match[1]) {\n return { href: match[1] } satisfies LinkAttrs\n }\n return false\n },\n })\n}\n","import {\n addMark,\n defineCommands,\n defineMarkSpec,\n expandMark,\n removeMark,\n toggleMark,\n union,\n type Extension,\n type PlainExtension,\n type Union,\n} from '@prosekit/core'\nimport { InputRule } from '@prosekit/pm/inputrules'\n\nimport { defineEnterRule } from '../enter-rule/index.ts'\nimport { defineInputRule } from '../input-rule/index.ts'\nimport { defineMarkRule } from '../mark-rule/index.ts'\n\nimport { defineLinkPasteRule } from './link-paste-rule.ts'\nimport { LINK_ENTER_RE, LINK_INPUT_RE, LINK_MARK_RE } from './link-regex.ts'\nimport type { LinkAttrs } from './link-types.ts'\n\nexport { defineLinkPasteRule }\nexport type { LinkAttrs }\n\n/**\n * @internal\n */\nexport type LinkSpecExtension = Extension<{\n Marks: {\n link: LinkAttrs\n }\n}>\n\n/**\n * @internal\n */\nexport function defineLinkSpec(): LinkSpecExtension {\n return defineMarkSpec<'link', LinkAttrs>({\n name: 'link',\n inclusive: false,\n attrs: {\n href: { validate: 'string' },\n target: { default: null, validate: 'string|null' },\n rel: { default: null, validate: 'string|null' },\n },\n parseDOM: [\n {\n tag: 'a[href]',\n getAttrs: (dom: HTMLElement) => {\n return {\n href: dom.getAttribute('href') || '',\n target: dom.getAttribute('target') || null,\n rel: dom.getAttribute('rel') || null,\n }\n },\n },\n ],\n toDOM(node) {\n const { href, target, rel } = node.attrs as LinkAttrs\n return ['a', { href, target, rel }, 0]\n },\n })\n}\n\n/**\n * @internal\n */\nexport type LinkCommandsExtension = Extension<{\n Commands: {\n addLink: [attrs: LinkAttrs]\n removeLink: []\n toggleLink: [attrs: LinkAttrs]\n expandLink: []\n }\n}>\n\nexport function defineLinkCommands(): LinkCommandsExtension {\n return defineCommands({\n addLink: (attrs: LinkAttrs) => addMark({ type: 'link', attrs }),\n removeLink: () => removeMark({ type: 'link' }),\n toggleLink: (attrs: LinkAttrs) => toggleMark({ type: 'link', attrs }),\n expandLink: () => expandMark({ type: 'link' }),\n })\n}\n\n/**\n * Apply link marks after pressing Space.\n *\n * @internal\n */\nexport function defineLinkInputRule(): PlainExtension {\n return defineInputRule(\n new InputRule(LINK_INPUT_RE, (state, match, from) => {\n const href = match[1]\n if (!href) return null\n\n const mark = state.schema.marks.link.create({ href })\n return state.tr.addMark(from, from + href.length, mark).insertText(' ')\n }),\n )\n}\n\n/**\n * Apply link marks after typing Enter.\n *\n * @internal\n */\nexport function defineLinkEnterRule(): PlainExtension {\n return defineEnterRule({\n regex: LINK_ENTER_RE,\n handler: ({ state, from, match }) => {\n const href = match[1]\n if (!href) return null\n\n const mark = state.schema.marks.link.create({ href })\n const tr = state.tr.addMark(from, from + href.length, mark)\n return tr.docChanged ? tr : null\n },\n })\n}\n\n/**\n * Apply and remove link marks to the text during typing.\n *\n * @internal\n */\nexport function defineLinkMarkRule(): PlainExtension {\n return defineMarkRule({\n regex: LINK_MARK_RE,\n type: 'link',\n attrs: (match) => ({ href: match[1] }),\n })\n}\n\n/**\n * @internal\n */\nexport type LinkExtension = Union<[LinkSpecExtension, LinkCommandsExtension]>\n\n/**\n * @public\n */\nexport function defineLink(): LinkExtension {\n return union(\n defineLinkSpec(),\n defineLinkCommands(),\n defineLinkInputRule(),\n defineLinkEnterRule(),\n defineLinkPasteRule(),\n )\n}\n"],"mappings":";;;;;;;AAIA,MAAM,iBACJ;AAGF,MAAM,2BAA2B;AAEjC,MAAM,oBAAoB,MAAM,2BAA2B;AAElC,KAAe;AAGxC,MAAM,uBAEF,6HAiBY,iBACJ;AAmCZ,MAAM,qBAAqB,uBAAuB,oBAAoB;AAEtE,MAAM,qBAAqB,uBAAuB,oBAAoB;AAEtE,MAAM,oBAAoB,uBAAuB;AAEjD,MAAa,gBAAwB,IAAI,OAAO,oBAAoB,KAAK;AACzE,MAAa,gBAAwB,IAAI,OAAO,oBAAoB,KAAK;AACzE,MAAa,eAAuB,IAAI,OAAO,mBAAmB,KAAK;;;;;;ACpEvE,SAAgB,sBAAsC;AACpD,QAAO,oBAAoB;EACzB,MAAM;EACN,OAAO;EACP,WAAW,UAA8C;AACvD,OAAI,MAAM,GACR,QAAO,EAAE,MAAM,MAAM,IAAI;AAE3B,UAAO;;EAEV,CAAC;;;;;;;ACiBJ,SAAgB,iBAAoC;AAClD,QAAO,eAAkC;EACvC,MAAM;EACN,WAAW;EACX,OAAO;GACL,MAAM,EAAE,UAAU,UAAU;GAC5B,QAAQ;IAAE,SAAS;IAAM,UAAU;IAAe;GAClD,KAAK;IAAE,SAAS;IAAM,UAAU;IAAe;GAChD;EACD,UAAU,CACR;GACE,KAAK;GACL,WAAW,QAAqB;AAC9B,WAAO;KACL,MAAM,IAAI,aAAa,OAAO,IAAI;KAClC,QAAQ,IAAI,aAAa,SAAS,IAAI;KACtC,KAAK,IAAI,aAAa,MAAM,IAAI;KACjC;;GAEJ,CACF;EACD,MAAM,MAAM;GACV,MAAM,EAAE,MAAM,QAAQ,QAAQ,KAAK;AACnC,UAAO;IAAC;IAAK;KAAE;KAAM;KAAQ;KAAK;IAAE;IAAE;;EAEzC,CAAC;;AAeJ,SAAgB,qBAA4C;AAC1D,QAAO,eAAe;EACpB,UAAU,UAAqB,QAAQ;GAAE,MAAM;GAAQ;GAAO,CAAC;EAC/D,kBAAkB,WAAW,EAAE,MAAM,QAAQ,CAAC;EAC9C,aAAa,UAAqB,WAAW;GAAE,MAAM;GAAQ;GAAO,CAAC;EACrE,kBAAkB,WAAW,EAAE,MAAM,QAAQ,CAAC;EAC/C,CAAC;;;;;;;AAQJ,SAAgB,sBAAsC;AACpD,QAAO,gBACL,IAAI,UAAU,gBAAgB,OAAO,OAAO,SAAS;EACnD,MAAM,OAAO,MAAM;AACnB,MAAI,CAAC,KAAM,QAAO;EAElB,MAAM,OAAO,MAAM,OAAO,MAAM,KAAK,OAAO,EAAE,MAAM,CAAC;AACrD,SAAO,MAAM,GAAG,QAAQ,MAAM,OAAO,KAAK,QAAQ,KAAK,CAAC,WAAW,IAAI;GACvE,CACH;;;;;;;AAQH,SAAgB,sBAAsC;AACpD,QAAO,gBAAgB;EACrB,OAAO;EACP,UAAU,EAAE,OAAO,MAAM,YAAY;GACnC,MAAM,OAAO,MAAM;AACnB,OAAI,CAAC,KAAM,QAAO;GAElB,MAAM,OAAO,MAAM,OAAO,MAAM,KAAK,OAAO,EAAE,MAAM,CAAC;GACrD,MAAM,KAAK,MAAM,GAAG,QAAQ,MAAM,OAAO,KAAK,QAAQ,KAAK;AAC3D,UAAO,GAAG,aAAa,KAAK;;EAE/B,CAAC;;;;;;;AAQJ,SAAgB,qBAAqC;AACnD,QAAO,eAAe;EACpB,OAAO;EACP,MAAM;EACN,QAAQ,WAAW,EAAE,MAAM,MAAM,IAAI;EACtC,CAAC;;;;;AAWJ,SAAgB,aAA4B;AAC1C,QAAO,MACL,gBAAgB,EAChB,oBAAoB,EACpB,qBAAqB,EACrB,qBAAqB,EACrB,qBAAqB,CACtB"}
|