@prosekit/extensions 0.11.3 → 0.11.5
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/commit/style.css +2 -0
- package/dist/commit/style.css.map +1 -0
- package/dist/commit/style.js +1 -0
- package/dist/{drop-indicator-B8P652g2.js → drop-indicator-D1eHOhSi.js} +6 -5
- package/dist/drop-indicator-D1eHOhSi.js.map +1 -0
- package/dist/enter-rule-RdhEA900.js +2 -1
- package/dist/enter-rule-RdhEA900.js.map +1 -0
- package/dist/gap-cursor/style.css +2 -0
- package/dist/gap-cursor/style.css.map +1 -0
- package/dist/gap-cursor/style.js +1 -0
- package/dist/{input-rule-Gji4N7Oe.js → input-rule-B17tpW4m.js} +3 -3
- package/dist/input-rule-B17tpW4m.js.map +1 -0
- package/dist/list/style.css +2 -0
- package/dist/list/style.css.map +1 -0
- package/dist/list/style.js +1 -0
- package/dist/loro/style.css +2 -0
- package/dist/loro/style.css.map +1 -0
- package/dist/loro/style.js +1 -0
- package/dist/{mark-rule-D7zaa32n.js → mark-rule-BCqIZMDu.js} +3 -3
- package/dist/mark-rule-BCqIZMDu.js.map +1 -0
- package/dist/{paste-rule-Cca3n5TA.js → paste-rule-DIEJKIje.js} +5 -15
- package/dist/paste-rule-DIEJKIje.js.map +1 -0
- package/dist/placeholder/style.css +2 -0
- package/dist/placeholder/style.css.map +1 -0
- package/dist/placeholder/style.js +1 -0
- package/dist/prosekit-extensions-autocomplete.d.ts +2 -1
- package/dist/prosekit-extensions-autocomplete.d.ts.map +1 -0
- package/dist/prosekit-extensions-autocomplete.js +2 -9
- package/dist/prosekit-extensions-autocomplete.js.map +1 -0
- package/dist/prosekit-extensions-blockquote.d.ts +2 -1
- package/dist/prosekit-extensions-blockquote.d.ts.map +1 -0
- package/dist/prosekit-extensions-blockquote.js +4 -4
- package/dist/prosekit-extensions-blockquote.js.map +1 -0
- package/dist/prosekit-extensions-bold.d.ts +2 -1
- package/dist/prosekit-extensions-bold.d.ts.map +1 -0
- package/dist/prosekit-extensions-bold.js +3 -2
- package/dist/prosekit-extensions-bold.js.map +1 -0
- package/dist/prosekit-extensions-code-block.d.ts +2 -1
- package/dist/prosekit-extensions-code-block.d.ts.map +1 -0
- package/dist/prosekit-extensions-code-block.js +5 -6
- package/dist/prosekit-extensions-code-block.js.map +1 -0
- package/dist/prosekit-extensions-code.d.ts +2 -1
- package/dist/prosekit-extensions-code.d.ts.map +1 -0
- package/dist/prosekit-extensions-code.js +3 -2
- package/dist/prosekit-extensions-code.js.map +1 -0
- package/dist/prosekit-extensions-commit.d.ts +2 -1
- package/dist/prosekit-extensions-commit.d.ts.map +1 -0
- package/dist/prosekit-extensions-commit.js +11 -13
- package/dist/prosekit-extensions-commit.js.map +1 -0
- package/dist/prosekit-extensions-doc.d.ts +2 -1
- package/dist/prosekit-extensions-doc.d.ts.map +1 -0
- package/dist/prosekit-extensions-doc.js +2 -1
- package/dist/prosekit-extensions-doc.js.map +1 -0
- package/dist/prosekit-extensions-drop-cursor.d.ts +2 -1
- package/dist/prosekit-extensions-drop-cursor.d.ts.map +1 -0
- package/dist/prosekit-extensions-drop-cursor.js +2 -1
- package/dist/prosekit-extensions-drop-cursor.js.map +1 -0
- package/dist/prosekit-extensions-drop-indicator.d.ts +2 -1
- package/dist/prosekit-extensions-drop-indicator.d.ts.map +1 -0
- package/dist/prosekit-extensions-drop-indicator.js +1 -1
- package/dist/prosekit-extensions-enter-rule.d.ts +2 -1
- package/dist/prosekit-extensions-enter-rule.d.ts.map +1 -0
- package/dist/prosekit-extensions-file.d.ts +2 -1
- package/dist/prosekit-extensions-file.d.ts.map +1 -0
- package/dist/prosekit-extensions-file.js +4 -16
- package/dist/prosekit-extensions-file.js.map +1 -0
- package/dist/prosekit-extensions-gap-cursor.d.ts +2 -2
- package/dist/prosekit-extensions-gap-cursor.d.ts.map +1 -0
- package/dist/prosekit-extensions-gap-cursor.js +2 -1
- package/dist/prosekit-extensions-gap-cursor.js.map +1 -0
- package/dist/prosekit-extensions-hard-break.d.ts +2 -1
- package/dist/prosekit-extensions-hard-break.d.ts.map +1 -0
- package/dist/prosekit-extensions-hard-break.js +2 -1
- package/dist/prosekit-extensions-hard-break.js.map +1 -0
- package/dist/prosekit-extensions-heading.d.ts +2 -1
- package/dist/prosekit-extensions-heading.d.ts.map +1 -0
- package/dist/prosekit-extensions-heading.js +5 -6
- package/dist/prosekit-extensions-heading.js.map +1 -0
- package/dist/prosekit-extensions-horizontal-rule.d.ts +2 -1
- package/dist/prosekit-extensions-horizontal-rule.d.ts.map +1 -0
- package/dist/prosekit-extensions-horizontal-rule.js +5 -6
- package/dist/prosekit-extensions-horizontal-rule.js.map +1 -0
- package/dist/prosekit-extensions-image.d.ts +2 -1
- package/dist/prosekit-extensions-image.d.ts.map +1 -0
- package/dist/prosekit-extensions-image.js +3 -3
- package/dist/prosekit-extensions-image.js.map +1 -0
- package/dist/prosekit-extensions-input-rule.d.ts +2 -1
- package/dist/prosekit-extensions-input-rule.d.ts.map +1 -0
- package/dist/prosekit-extensions-input-rule.js +1 -1
- package/dist/prosekit-extensions-italic.d.ts +2 -1
- package/dist/prosekit-extensions-italic.d.ts.map +1 -0
- package/dist/prosekit-extensions-italic.js +3 -2
- package/dist/prosekit-extensions-italic.js.map +1 -0
- package/dist/prosekit-extensions-link.d.ts +2 -1
- package/dist/prosekit-extensions-link.d.ts.map +1 -0
- package/dist/prosekit-extensions-link.js +6 -5
- package/dist/prosekit-extensions-link.js.map +1 -0
- package/dist/prosekit-extensions-list.d.ts +22 -21
- package/dist/prosekit-extensions-list.d.ts.map +1 -0
- package/dist/prosekit-extensions-list.js +6 -7
- package/dist/prosekit-extensions-list.js.map +1 -0
- package/dist/prosekit-extensions-loro.d.ts +14 -13
- package/dist/prosekit-extensions-loro.d.ts.map +1 -0
- package/dist/prosekit-extensions-loro.js +2 -1
- package/dist/prosekit-extensions-loro.js.map +1 -0
- package/dist/prosekit-extensions-mark-rule.d.ts +2 -1
- package/dist/prosekit-extensions-mark-rule.d.ts.map +1 -0
- package/dist/prosekit-extensions-mark-rule.js +1 -1
- package/dist/prosekit-extensions-mention.d.ts +2 -1
- package/dist/prosekit-extensions-mention.d.ts.map +1 -0
- package/dist/prosekit-extensions-mention.js +2 -1
- package/dist/prosekit-extensions-mention.js.map +1 -0
- package/dist/prosekit-extensions-mod-click-prevention.d.ts +2 -1
- package/dist/prosekit-extensions-mod-click-prevention.d.ts.map +1 -0
- package/dist/prosekit-extensions-mod-click-prevention.js +2 -1
- package/dist/prosekit-extensions-mod-click-prevention.js.map +1 -0
- package/dist/prosekit-extensions-paragraph.d.ts +2 -1
- package/dist/prosekit-extensions-paragraph.d.ts.map +1 -0
- package/dist/prosekit-extensions-paragraph.js +2 -1
- package/dist/prosekit-extensions-paragraph.js.map +1 -0
- package/dist/prosekit-extensions-paste-rule.d.ts +2 -1
- package/dist/prosekit-extensions-paste-rule.d.ts.map +1 -0
- package/dist/prosekit-extensions-paste-rule.js +1 -1
- package/dist/prosekit-extensions-placeholder.d.ts +2 -1
- package/dist/prosekit-extensions-placeholder.d.ts.map +1 -0
- package/dist/prosekit-extensions-placeholder.js +5 -4
- package/dist/prosekit-extensions-placeholder.js.map +1 -0
- package/dist/prosekit-extensions-readonly.d.ts +2 -1
- package/dist/prosekit-extensions-readonly.d.ts.map +1 -0
- package/dist/prosekit-extensions-readonly.js +2 -1
- package/dist/prosekit-extensions-readonly.js.map +1 -0
- package/dist/prosekit-extensions-search.d.ts +2 -1
- package/dist/prosekit-extensions-search.d.ts.map +1 -0
- package/dist/prosekit-extensions-search.js +3 -3
- package/dist/prosekit-extensions-search.js.map +1 -0
- package/dist/prosekit-extensions-strike.d.ts +2 -1
- package/dist/prosekit-extensions-strike.d.ts.map +1 -0
- package/dist/prosekit-extensions-strike.js +3 -2
- package/dist/prosekit-extensions-strike.js.map +1 -0
- package/dist/prosekit-extensions-table.d.ts +56 -114
- package/dist/prosekit-extensions-table.d.ts.map +1 -0
- package/dist/prosekit-extensions-table.js +3 -2
- package/dist/prosekit-extensions-text-align.d.ts +2 -1
- package/dist/prosekit-extensions-text-align.d.ts.map +1 -0
- package/dist/prosekit-extensions-text-align.js +2 -1
- package/dist/prosekit-extensions-text-align.js.map +1 -0
- package/dist/prosekit-extensions-text.d.ts +2 -1
- package/dist/prosekit-extensions-text.d.ts.map +1 -0
- package/dist/prosekit-extensions-text.js +2 -1
- package/dist/prosekit-extensions-text.js.map +1 -0
- package/dist/prosekit-extensions-underline.d.ts +2 -1
- package/dist/prosekit-extensions-underline.d.ts.map +1 -0
- package/dist/prosekit-extensions-underline.js +2 -1
- package/dist/prosekit-extensions-underline.js.map +1 -0
- package/dist/prosekit-extensions-virtual-selection.d.ts +2 -1
- package/dist/prosekit-extensions-virtual-selection.d.ts.map +1 -0
- package/dist/prosekit-extensions-virtual-selection.js +3 -3
- package/dist/prosekit-extensions-virtual-selection.js.map +1 -0
- package/dist/prosekit-extensions-yjs.d.ts +2 -1
- package/dist/prosekit-extensions-yjs.d.ts.map +1 -0
- package/dist/prosekit-extensions-yjs.js +2 -1
- package/dist/prosekit-extensions-yjs.js.map +1 -0
- package/dist/prosekit-extensions.d.ts +1 -1
- package/dist/prosekit-extensions.js +1 -0
- package/dist/search/style.css +2 -0
- package/dist/search/style.css.map +1 -0
- package/dist/search/style.js +1 -0
- package/dist/shiki-highlighter-chunk-DSPM0T27.d.ts +2 -1
- package/dist/shiki-highlighter-chunk-DSPM0T27.d.ts.map +1 -0
- package/dist/shiki-highlighter-chunk.js +3 -5
- package/dist/shiki-highlighter-chunk.js.map +1 -0
- package/dist/table/style.css +2 -0
- package/dist/table/style.css.map +1 -0
- package/dist/table/style.js +1 -0
- package/dist/table-Bi7WsMI3.js +297 -0
- package/dist/table-Bi7WsMI3.js.map +1 -0
- package/dist/virtual-selection/style.css +2 -0
- package/dist/virtual-selection/style.css.map +1 -0
- package/dist/virtual-selection/style.js +1 -0
- package/dist/yjs/style.css +2 -0
- package/dist/yjs/style.css.map +1 -0
- package/dist/yjs/style.js +1 -0
- package/package.json +10 -9
- package/src/autocomplete/autocomplete-helpers.ts +74 -0
- package/src/autocomplete/autocomplete-plugin.ts +186 -0
- package/src/autocomplete/autocomplete-rule.ts +117 -0
- package/src/autocomplete/autocomplete.spec.ts +132 -0
- package/src/autocomplete/autocomplete.ts +29 -0
- package/src/autocomplete/index.ts +9 -0
- package/src/blockquote/blockquote-commands.ts +32 -0
- package/src/blockquote/blockquote-input-rule.ts +14 -0
- package/src/blockquote/blockquote-keymap.spec.ts +45 -0
- package/src/blockquote/blockquote-keymap.ts +31 -0
- package/src/blockquote/blockquote-spec.ts +24 -0
- package/src/blockquote/blockquote.ts +34 -0
- package/src/blockquote/index.ts +14 -0
- package/src/bold/bold-commands.ts +23 -0
- package/src/bold/bold-input-rule.spec.ts +51 -0
- package/src/bold/bold-input-rule.ts +18 -0
- package/src/bold/bold-keymap.ts +14 -0
- package/src/bold/bold-spec.ts +53 -0
- package/src/bold/bold.ts +32 -0
- package/src/bold/index.ts +14 -0
- package/src/code/code-commands.ts +23 -0
- package/src/code/code-input-rule.ts +18 -0
- package/src/code/code-keymap.ts +14 -0
- package/src/code/code-spec.ts +28 -0
- package/src/code/code.ts +32 -0
- package/src/code/index.ts +14 -0
- package/src/code-block/code-block-commands.ts +44 -0
- package/src/code-block/code-block-highlight.ts +40 -0
- package/src/code-block/code-block-input-rule.ts +36 -0
- package/src/code-block/code-block-keymap.ts +61 -0
- package/src/code-block/code-block-shiki.ts +58 -0
- package/src/code-block/code-block-spec.spec.ts +164 -0
- package/src/code-block/code-block-spec.ts +71 -0
- package/src/code-block/code-block-types.ts +8 -0
- package/src/code-block/code-block.ts +46 -0
- package/src/code-block/index.ts +32 -0
- package/src/code-block/shiki-bundle.ts +8 -0
- package/src/code-block/shiki-highlighter-chunk.ts +84 -0
- package/src/code-block/shiki-highlighter.ts +22 -0
- package/src/code-block/shiki-parser.ts +36 -0
- package/src/commit/index.ts +330 -0
- package/src/commit/style.css +7 -0
- package/src/doc/index.ts +21 -0
- package/src/drop-cursor/drop-cursor.ts +46 -0
- package/src/drop-cursor/index.ts +5 -0
- package/src/drop-indicator/drop-indicator-facet.ts +84 -0
- package/src/drop-indicator/drop-indicator-plugin.ts +147 -0
- package/src/drop-indicator/drop-indicator.ts +37 -0
- package/src/drop-indicator/drop-target.ts +168 -0
- package/src/drop-indicator/index.ts +14 -0
- package/src/drop-indicator/types.ts +90 -0
- package/src/enter-rule/index.ts +241 -0
- package/src/file/file-drop-handler.ts +75 -0
- package/src/file/file-paste-handler.spec.ts +95 -0
- package/src/file/file-paste-handler.ts +59 -0
- package/src/file/file-upload.ts +119 -0
- package/src/file/helpers.ts +39 -0
- package/src/file/index.ts +16 -0
- package/src/gap-cursor/gap-cursor.ts +28 -0
- package/src/gap-cursor/index.ts +4 -0
- package/src/gap-cursor/style.css +25 -0
- package/src/hard-break/hard-break-commands.ts +31 -0
- package/src/hard-break/hard-break-keymap.spec.ts +45 -0
- package/src/hard-break/hard-break-keymap.ts +16 -0
- package/src/hard-break/hard-break-spec.ts +31 -0
- package/src/hard-break/hard-break.ts +32 -0
- package/src/hard-break/index.ts +13 -0
- package/src/heading/heading-commands.ts +37 -0
- package/src/heading/heading-input-rule.ts +22 -0
- package/src/heading/heading-keymap.spec.ts +53 -0
- package/src/heading/heading-keymap.ts +40 -0
- package/src/heading/heading-spec.ts +39 -0
- package/src/heading/heading-types.ts +3 -0
- package/src/heading/heading.ts +34 -0
- package/src/heading/index.ts +15 -0
- package/src/horizontal-rule/horizontal-rule-commands.spec.ts +61 -0
- package/src/horizontal-rule/horizontal-rule-commands.ts +37 -0
- package/src/horizontal-rule/horizontal-rule-input-rule.spec.ts +61 -0
- package/src/horizontal-rule/horizontal-rule-input-rule.ts +26 -0
- package/src/horizontal-rule/horizontal-rule-spec.ts +21 -0
- package/src/horizontal-rule/horizontal-rule.ts +29 -0
- package/src/horizontal-rule/index.ts +14 -0
- package/src/image/image-commands.ts +27 -0
- package/src/image/image-spec.ts +72 -0
- package/src/image/image.ts +25 -0
- package/src/image/index.ts +13 -0
- package/src/index.ts +1 -0
- package/src/input-rule/index.ts +237 -0
- package/src/italic/index.ts +14 -0
- package/src/italic/italic-commands.spec.ts +75 -0
- package/src/italic/italic-commands.ts +23 -0
- package/src/italic/italic-input-rule.spec.ts +25 -0
- package/src/italic/italic-input-rule.ts +18 -0
- package/src/italic/italic-keymap.ts +14 -0
- package/src/italic/italic-spec.ts +35 -0
- package/src/italic/italic.ts +34 -0
- package/src/link/index.spec.ts +88 -0
- package/src/link/index.ts +156 -0
- package/src/link/link-paste-rule.spec.ts +194 -0
- package/src/link/link-paste-rule.ts +22 -0
- package/src/link/link-regex.spec.ts +82 -0
- package/src/link/link-regex.ts +79 -0
- package/src/link/link-types.ts +8 -0
- package/src/list/index.ts +25 -0
- package/src/list/list-commands.ts +61 -0
- package/src/list/list-drop-indicator.ts +37 -0
- package/src/list/list-input-rules.ts +14 -0
- package/src/list/list-keymap.spec.ts +39 -0
- package/src/list/list-keymap.ts +48 -0
- package/src/list/list-plugins.ts +35 -0
- package/src/list/list-serializer.ts +38 -0
- package/src/list/list-spec.ts +60 -0
- package/src/list/list-types.spec.ts +10 -0
- package/src/list/list-types.ts +23 -0
- package/src/list/list.spec.ts +134 -0
- package/src/list/list.ts +38 -0
- package/src/list/style.css +128 -0
- package/src/loro/index.ts +17 -0
- package/src/loro/loro-commands.ts +27 -0
- package/src/loro/loro-cursor-plugin.ts +28 -0
- package/src/loro/loro-keymap.ts +23 -0
- package/src/loro/loro-sync-plugin.ts +14 -0
- package/src/loro/loro-undo-plugin.ts +12 -0
- package/src/loro/loro.ts +75 -0
- package/src/loro/style.css +33 -0
- package/src/mark-rule/apply.ts +129 -0
- package/src/mark-rule/index.ts +2 -0
- package/src/mark-rule/mark-rule.spec.ts +123 -0
- package/src/mark-rule/mark-rule.ts +48 -0
- package/src/mark-rule/range.ts +107 -0
- package/src/mark-rule/types.ts +30 -0
- package/src/mention/index.ts +90 -0
- package/src/mod-click-prevention/index.ts +35 -0
- package/src/paragraph/index.ts +7 -0
- package/src/paragraph/paragraph-commands.ts +29 -0
- package/src/paragraph/paragraph-keymap.ts +15 -0
- package/src/paragraph/paragraph-spec.ts +31 -0
- package/src/paragraph/paragraph.ts +37 -0
- package/src/paste-rule/index.ts +10 -0
- package/src/paste-rule/mark-paste-rule.spec.ts +112 -0
- package/src/paste-rule/mark-paste-rule.ts +194 -0
- package/src/paste-rule/paste-rule-plugin.ts +53 -0
- package/src/paste-rule/paste-rule.spec.ts +96 -0
- package/src/paste-rule/paste-rule.ts +60 -0
- package/src/paste-rule/split-text-by-regex.spec.ts +97 -0
- package/src/paste-rule/split-text-by-regex.ts +44 -0
- package/src/placeholder/index.ts +113 -0
- package/src/placeholder/style.css +7 -0
- package/src/readonly/index.ts +22 -0
- package/src/search/index.ts +140 -0
- package/src/search/style.css +13 -0
- package/src/strike/index.ts +101 -0
- package/src/table/index.ts +53 -0
- package/src/table/style.css +42 -0
- package/src/table/table-commands/delete-cell-selection.spec.ts +41 -0
- package/src/table/table-commands/delete-cell-selection.ts +1 -0
- package/src/table/table-commands/exit-table.spec.ts +45 -0
- package/src/table/table-commands/exit-table.ts +49 -0
- package/src/table/table-commands/insert-table.spec.ts +39 -0
- package/src/table/table-commands/insert-table.ts +80 -0
- package/src/table/table-commands/move-table-column.spec.ts +618 -0
- package/src/table/table-commands/move-table-column.ts +4 -0
- package/src/table/table-commands/move-table-row.spec.ts +380 -0
- package/src/table/table-commands/move-table-row.ts +4 -0
- package/src/table/table-commands/select-table-cell.spec.ts +34 -0
- package/src/table/table-commands/select-table-cell.ts +35 -0
- package/src/table/table-commands/select-table-column.spec.ts +33 -0
- package/src/table/table-commands/select-table-column.ts +39 -0
- package/src/table/table-commands/select-table-row.spec.ts +32 -0
- package/src/table/table-commands/select-table-row.ts +39 -0
- package/src/table/table-commands/select-table.spec.ts +36 -0
- package/src/table/table-commands/select-table.ts +50 -0
- package/src/table/table-commands.ts +110 -0
- package/src/table/table-drop-indicator.ts +40 -0
- package/src/table/table-plugins.ts +15 -0
- package/src/table/table-spec.spec.ts +113 -0
- package/src/table/table-spec.ts +109 -0
- package/src/table/table-utils.ts +16 -0
- package/src/table/table.ts +49 -0
- package/src/table/test-utils.ts +28 -0
- package/src/testing/clipboard.ts +58 -0
- package/src/testing/format-html.ts +5 -0
- package/src/testing/index.ts +161 -0
- package/src/testing/keyboard.ts +36 -0
- package/src/testing/markdown.ts +23 -0
- package/src/text/index.ts +24 -0
- package/src/text-align/index.ts +133 -0
- package/src/types/assert-type-equal.ts +8 -0
- package/src/underline/index.ts +83 -0
- package/src/virtual-selection/index.ts +100 -0
- package/src/virtual-selection/style.css +5 -0
- package/src/yjs/index.ts +22 -0
- package/src/yjs/style.css +31 -0
- package/src/yjs/yjs-commands.ts +27 -0
- package/src/yjs/yjs-cursor-plugin.ts +25 -0
- package/src/yjs/yjs-keymap.ts +23 -0
- package/src/yjs/yjs-sync-plugin.ts +23 -0
- package/src/yjs/yjs-undo-plugin.ts +87 -0
- package/src/yjs/yjs.ts +84 -0
- package/dist/table-C_qAMj5-.js +0 -734
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import {
|
|
2
|
+
describe,
|
|
3
|
+
expect,
|
|
4
|
+
it,
|
|
5
|
+
} from 'vitest'
|
|
6
|
+
|
|
7
|
+
import { splitTextByRegex } from './split-text-by-regex'
|
|
8
|
+
|
|
9
|
+
describe('splitTextByRegex', () => {
|
|
10
|
+
it('should return undefined when no matches are found', () => {
|
|
11
|
+
const result = splitTextByRegex('hello world', /\d+/g)
|
|
12
|
+
expect(result).toBeUndefined()
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
it('should split text with single match', () => {
|
|
16
|
+
const result = splitTextByRegex('hello 123 world', /\d+/g)
|
|
17
|
+
expect(result).toEqual([
|
|
18
|
+
['hello ', undefined],
|
|
19
|
+
['123', expect.objectContaining({ 0: '123', index: 6 })],
|
|
20
|
+
[' world', undefined],
|
|
21
|
+
])
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
it('should split text with multiple matches', () => {
|
|
25
|
+
const result = splitTextByRegex('abc 123 def 456 ghi', /\d+/g)
|
|
26
|
+
expect(result).toEqual([
|
|
27
|
+
['abc ', undefined],
|
|
28
|
+
['123', expect.objectContaining({ 0: '123', index: 4 })],
|
|
29
|
+
[' def ', undefined],
|
|
30
|
+
['456', expect.objectContaining({ 0: '456', index: 12 })],
|
|
31
|
+
[' ghi', undefined],
|
|
32
|
+
])
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
it('should handle match at the beginning', () => {
|
|
36
|
+
const result = splitTextByRegex('123 hello', /\d+/g)
|
|
37
|
+
expect(result).toEqual([
|
|
38
|
+
['123', expect.objectContaining({ 0: '123', index: 0 })],
|
|
39
|
+
[' hello', undefined],
|
|
40
|
+
])
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
it('should handle match at the end', () => {
|
|
44
|
+
const result = splitTextByRegex('hello 123', /\d+/g)
|
|
45
|
+
expect(result).toEqual([
|
|
46
|
+
['hello ', undefined],
|
|
47
|
+
['123', expect.objectContaining({ 0: '123', index: 6 })],
|
|
48
|
+
])
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
it('should handle consecutive matches', () => {
|
|
52
|
+
const result = splitTextByRegex('123456', /\d/g)
|
|
53
|
+
expect(result).toEqual([
|
|
54
|
+
['1', expect.objectContaining({ 0: '1', index: 0 })],
|
|
55
|
+
['2', expect.objectContaining({ 0: '2', index: 1 })],
|
|
56
|
+
['3', expect.objectContaining({ 0: '3', index: 2 })],
|
|
57
|
+
['4', expect.objectContaining({ 0: '4', index: 3 })],
|
|
58
|
+
['5', expect.objectContaining({ 0: '5', index: 4 })],
|
|
59
|
+
['6', expect.objectContaining({ 0: '6', index: 5 })],
|
|
60
|
+
])
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
it('should handle entire string match', () => {
|
|
64
|
+
const result = splitTextByRegex('123', /\d+/g)
|
|
65
|
+
expect(result).toEqual([
|
|
66
|
+
['123', expect.objectContaining({ 0: '123', index: 0 })],
|
|
67
|
+
])
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
it('should work with URL regex', () => {
|
|
71
|
+
const urlRegex = /https?:\/\/\S+/g
|
|
72
|
+
const result = splitTextByRegex('Visit https://example.com for more info', urlRegex)
|
|
73
|
+
expect(result).toEqual([
|
|
74
|
+
['Visit ', undefined],
|
|
75
|
+
['https://example.com', expect.objectContaining({ 0: 'https://example.com', index: 6 })],
|
|
76
|
+
[' for more info', undefined],
|
|
77
|
+
])
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
it('should reset regex lastIndex', () => {
|
|
81
|
+
const regex = /\d+/g
|
|
82
|
+
regex.lastIndex = 5 // Set to non-zero
|
|
83
|
+
const result = splitTextByRegex('123 456', regex)
|
|
84
|
+
expect(result).toEqual([
|
|
85
|
+
['123', expect.objectContaining({ 0: '123', index: 0 })],
|
|
86
|
+
[' ', undefined],
|
|
87
|
+
['456', expect.objectContaining({ 0: '456', index: 4 })],
|
|
88
|
+
])
|
|
89
|
+
expect(regex.lastIndex).toBe(0) // Should be reset
|
|
90
|
+
})
|
|
91
|
+
|
|
92
|
+
it('should return undefined for zero-width matches', () => {
|
|
93
|
+
const regex = /(?=b)/g
|
|
94
|
+
const result = splitTextByRegex('abc', regex)
|
|
95
|
+
expect(result).toBeUndefined()
|
|
96
|
+
})
|
|
97
|
+
})
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Splits text into chunks based on regex matches, preserving both matched and unmatched segments.
|
|
3
|
+
* Returns an array of tuples where each tuple contains a text segment and either the match data
|
|
4
|
+
* (for matched segments) or undefined (for unmatched segments).
|
|
5
|
+
*/
|
|
6
|
+
export function splitTextByRegex(
|
|
7
|
+
text: string,
|
|
8
|
+
regex: RegExp,
|
|
9
|
+
): Array<[string, RegExpExecArray | undefined]> | undefined {
|
|
10
|
+
regex.lastIndex = 0
|
|
11
|
+
|
|
12
|
+
const chunks: Array<[string, RegExpExecArray | undefined]> = []
|
|
13
|
+
let lastIndex = 0
|
|
14
|
+
let match: RegExpExecArray | null
|
|
15
|
+
let matched = false
|
|
16
|
+
|
|
17
|
+
while ((match = regex.exec(text))) {
|
|
18
|
+
const start = match.index
|
|
19
|
+
const end = regex.lastIndex
|
|
20
|
+
|
|
21
|
+
// Push the unmatched prefix, if any.
|
|
22
|
+
if (start > lastIndex) {
|
|
23
|
+
chunks.push([text.slice(lastIndex, start), undefined])
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Push the matched segment.
|
|
27
|
+
chunks.push([text.slice(start, end), match])
|
|
28
|
+
matched = true
|
|
29
|
+
|
|
30
|
+
if (lastIndex === end) {
|
|
31
|
+
// Safeguard against zero-width matches that would otherwise cause an infinite loop.
|
|
32
|
+
return
|
|
33
|
+
}
|
|
34
|
+
lastIndex = end
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (matched && lastIndex < text.length) {
|
|
38
|
+
chunks.push([text.slice(lastIndex), undefined])
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
regex.lastIndex = 0
|
|
42
|
+
|
|
43
|
+
return matched ? chunks : undefined
|
|
44
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import {
|
|
2
|
+
definePlugin,
|
|
3
|
+
isInCodeBlock,
|
|
4
|
+
maybeRun,
|
|
5
|
+
type PlainExtension,
|
|
6
|
+
} from '@prosekit/core'
|
|
7
|
+
import type { ProseMirrorNode } from '@prosekit/pm/model'
|
|
8
|
+
import {
|
|
9
|
+
Plugin,
|
|
10
|
+
PluginKey,
|
|
11
|
+
type EditorState,
|
|
12
|
+
} from '@prosekit/pm/state'
|
|
13
|
+
import {
|
|
14
|
+
Decoration,
|
|
15
|
+
DecorationSet,
|
|
16
|
+
} from '@prosekit/pm/view'
|
|
17
|
+
|
|
18
|
+
import { findTable } from '../table'
|
|
19
|
+
|
|
20
|
+
export interface PlaceholderOptions {
|
|
21
|
+
/**
|
|
22
|
+
* The placeholder to use. It can be a static string or a function that
|
|
23
|
+
* receives the current editor state and returns a string.
|
|
24
|
+
*/
|
|
25
|
+
placeholder: string | ((state: EditorState) => string)
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* By default, the placeholder text will be shown whenever the current text
|
|
29
|
+
* cursor is in an empty text node and it's not inside a code block or a
|
|
30
|
+
* table node.
|
|
31
|
+
*
|
|
32
|
+
* If you only want to show the placeholder when the whole doc is empty, you
|
|
33
|
+
* can set this option to 'doc'.
|
|
34
|
+
*
|
|
35
|
+
* You can also pass a function that receives the current editor state and
|
|
36
|
+
* returns a boolean value to determine whether the placeholder should be
|
|
37
|
+
* shown.
|
|
38
|
+
*
|
|
39
|
+
* @default 'block'
|
|
40
|
+
*/
|
|
41
|
+
strategy?: 'doc' | 'block' | ((state: EditorState) => boolean)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Add a placeholder text to the editor when the current block or document is
|
|
46
|
+
* empty.
|
|
47
|
+
*/
|
|
48
|
+
export function definePlaceholder(options: PlaceholderOptions): PlainExtension {
|
|
49
|
+
return definePlugin(createPlaceholderPlugin(options))
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function createPlaceholderPlugin({
|
|
53
|
+
placeholder,
|
|
54
|
+
strategy = 'block',
|
|
55
|
+
}: PlaceholderOptions): Plugin {
|
|
56
|
+
return new Plugin({
|
|
57
|
+
key: new PluginKey('prosekit-placeholder'),
|
|
58
|
+
props: {
|
|
59
|
+
decorations: (state) => {
|
|
60
|
+
const strategyFn = typeof strategy === 'function'
|
|
61
|
+
? strategy
|
|
62
|
+
: strategy === 'doc'
|
|
63
|
+
? docStrategy
|
|
64
|
+
: defaultStrategy
|
|
65
|
+
|
|
66
|
+
if (!strategyFn(state)) {
|
|
67
|
+
return null
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const placeholderText: string = maybeRun(placeholder, state)
|
|
71
|
+
const deco = createPlaceholderDecoration(state, placeholderText)
|
|
72
|
+
if (!deco) {
|
|
73
|
+
return null
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return DecorationSet.create(state.doc, [deco])
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
})
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function defaultStrategy(state: EditorState): boolean {
|
|
83
|
+
return !isInCodeBlock(state.selection) && !findTable(state.selection.$from)
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function docStrategy(state: EditorState): boolean {
|
|
87
|
+
return isDocEmpty(state.doc) && defaultStrategy(state)
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function isDocEmpty(doc: ProseMirrorNode) {
|
|
91
|
+
return doc.childCount <= 1 && !doc.firstChild?.content.size
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function createPlaceholderDecoration(
|
|
95
|
+
state: EditorState,
|
|
96
|
+
placeholderText: string,
|
|
97
|
+
): Decoration | null {
|
|
98
|
+
if (!placeholderText) return null
|
|
99
|
+
|
|
100
|
+
const { selection } = state
|
|
101
|
+
if (!selection.empty) return null
|
|
102
|
+
|
|
103
|
+
const $pos = selection.$anchor
|
|
104
|
+
const node = $pos.parent
|
|
105
|
+
if (node.content.size > 0) return null
|
|
106
|
+
|
|
107
|
+
const before = $pos.before()
|
|
108
|
+
|
|
109
|
+
return Decoration.node(before, before + node.nodeSize, {
|
|
110
|
+
'class': 'prosekit-placeholder',
|
|
111
|
+
'data-placeholder': placeholderText,
|
|
112
|
+
})
|
|
113
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import {
|
|
2
|
+
definePlugin,
|
|
3
|
+
type PlainExtension,
|
|
4
|
+
} from '@prosekit/core'
|
|
5
|
+
import {
|
|
6
|
+
PluginKey,
|
|
7
|
+
ProseMirrorPlugin,
|
|
8
|
+
} from '@prosekit/pm/state'
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Make the editor read-only.
|
|
12
|
+
*/
|
|
13
|
+
export function defineReadonly(): PlainExtension {
|
|
14
|
+
return definePlugin(plugin)
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const plugin = new ProseMirrorPlugin({
|
|
18
|
+
key: new PluginKey('prosekey-readonly'),
|
|
19
|
+
props: {
|
|
20
|
+
editable: () => false,
|
|
21
|
+
},
|
|
22
|
+
})
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import {
|
|
2
|
+
defineCommands,
|
|
3
|
+
definePlugin,
|
|
4
|
+
type Extension,
|
|
5
|
+
type PlainExtension,
|
|
6
|
+
} from '@prosekit/core'
|
|
7
|
+
import type { Command } from '@prosekit/pm/state'
|
|
8
|
+
import type { EditorView } from '@prosekit/pm/view'
|
|
9
|
+
import {
|
|
10
|
+
findNext,
|
|
11
|
+
findNextNoWrap,
|
|
12
|
+
findPrev,
|
|
13
|
+
findPrevNoWrap,
|
|
14
|
+
replaceAll,
|
|
15
|
+
replaceCurrent,
|
|
16
|
+
replaceNext,
|
|
17
|
+
replaceNextNoWrap,
|
|
18
|
+
search,
|
|
19
|
+
SearchQuery,
|
|
20
|
+
} from 'prosemirror-search'
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Options for {@link defineSearchQuery}
|
|
24
|
+
*
|
|
25
|
+
* @public
|
|
26
|
+
*/
|
|
27
|
+
export interface SearchQueryOptions {
|
|
28
|
+
/**
|
|
29
|
+
* The search string (or regular expression).
|
|
30
|
+
*/
|
|
31
|
+
search: string
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* The replace text.
|
|
35
|
+
*/
|
|
36
|
+
replace?: string
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Indicates whether the search is case-sensitive
|
|
40
|
+
*
|
|
41
|
+
* @default false
|
|
42
|
+
*/
|
|
43
|
+
caseSensitive?: boolean
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* By default, string search will replace `\n`, `\r`, and `\t` in the query
|
|
47
|
+
* with newline, return, and tab characters. When this is set to true, that
|
|
48
|
+
* behavior is disabled.
|
|
49
|
+
*
|
|
50
|
+
* @default false
|
|
51
|
+
*/
|
|
52
|
+
literal?: boolean
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* When true, the search string is interpreted as a regular expression.
|
|
56
|
+
*
|
|
57
|
+
* @default false
|
|
58
|
+
*/
|
|
59
|
+
regexp?: boolean
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Enable whole-word matching.
|
|
63
|
+
*
|
|
64
|
+
* @default false
|
|
65
|
+
*/
|
|
66
|
+
wholeWord?: boolean
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Defines an extension that stores a current search query and replace string.
|
|
71
|
+
*
|
|
72
|
+
* @public
|
|
73
|
+
*/
|
|
74
|
+
export function defineSearchQuery(options: SearchQueryOptions): PlainExtension {
|
|
75
|
+
const query = new SearchQuery(options)
|
|
76
|
+
return definePlugin(search({ initialQuery: query }))
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Scrolls the active search match into view.
|
|
81
|
+
*/
|
|
82
|
+
function scrollActiveIntoView(view: EditorView) {
|
|
83
|
+
if (view.isDestroyed) return
|
|
84
|
+
const active = view.dom.querySelector('.ProseMirror-active-search-match')
|
|
85
|
+
active?.scrollIntoView({
|
|
86
|
+
block: 'nearest',
|
|
87
|
+
inline: 'nearest',
|
|
88
|
+
behavior: 'smooth',
|
|
89
|
+
})
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Wraps a command and scrolls the active search match into view when the command
|
|
94
|
+
* is applied.
|
|
95
|
+
*/
|
|
96
|
+
function withScrollActiveIntoView(command: Command): Command {
|
|
97
|
+
return (state, dispatch, view) => {
|
|
98
|
+
const result = command(state, dispatch, view)
|
|
99
|
+
if (result && dispatch && view) {
|
|
100
|
+
// Add a small delay because the command itself will handle scrolling if
|
|
101
|
+
// the view is focused.
|
|
102
|
+
setTimeout(() => scrollActiveIntoView(view), 50)
|
|
103
|
+
}
|
|
104
|
+
return result
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* @internal
|
|
110
|
+
*/
|
|
111
|
+
export type SearchCommandsExtension = Extension<{
|
|
112
|
+
Commands: {
|
|
113
|
+
findNext: []
|
|
114
|
+
findPrev: []
|
|
115
|
+
findNextNoWrap: []
|
|
116
|
+
findPrevNoWrap: []
|
|
117
|
+
replaceNext: []
|
|
118
|
+
replaceNextNoWrap: []
|
|
119
|
+
replaceCurrent: []
|
|
120
|
+
replaceAll: []
|
|
121
|
+
}
|
|
122
|
+
}>
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Defines commands for search and replace.
|
|
126
|
+
*
|
|
127
|
+
* @public
|
|
128
|
+
*/
|
|
129
|
+
export function defineSearchCommands(): SearchCommandsExtension {
|
|
130
|
+
return defineCommands({
|
|
131
|
+
findNext: () => withScrollActiveIntoView(findNext),
|
|
132
|
+
findPrev: () => withScrollActiveIntoView(findPrev),
|
|
133
|
+
findNextNoWrap: () => withScrollActiveIntoView(findNextNoWrap),
|
|
134
|
+
findPrevNoWrap: () => withScrollActiveIntoView(findPrevNoWrap),
|
|
135
|
+
replaceNext: () => withScrollActiveIntoView(replaceNext),
|
|
136
|
+
replaceNextNoWrap: () => withScrollActiveIntoView(replaceNextNoWrap),
|
|
137
|
+
replaceCurrent: () => withScrollActiveIntoView(replaceCurrent),
|
|
138
|
+
replaceAll: () => withScrollActiveIntoView(replaceAll),
|
|
139
|
+
})
|
|
140
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
.ProseMirror-search-match {
|
|
2
|
+
border-radius: 2px;
|
|
3
|
+
background-color: #ffff0054;
|
|
4
|
+
box-shadow: 0 0 0 2px #ffff0054;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
.ProseMirror.ProseMirror-focused .ProseMirror-active-search-match::selection,
|
|
8
|
+
.ProseMirror:not(.ProseMirror-focused) .ProseMirror-active-search-match {
|
|
9
|
+
border-radius: 2px;
|
|
10
|
+
background-color: #ff6a0054;
|
|
11
|
+
box-shadow: 0 0 0 2px #ff6a0054;
|
|
12
|
+
scroll-margin: 8px;
|
|
13
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import {
|
|
2
|
+
canUseRegexLookbehind,
|
|
3
|
+
defineCommands,
|
|
4
|
+
defineKeymap,
|
|
5
|
+
defineMarkSpec,
|
|
6
|
+
toggleMark,
|
|
7
|
+
union,
|
|
8
|
+
type Extension,
|
|
9
|
+
type PlainExtension,
|
|
10
|
+
type Union,
|
|
11
|
+
} from '@prosekit/core'
|
|
12
|
+
import type { Attrs } from '@prosekit/pm/model'
|
|
13
|
+
|
|
14
|
+
import { defineMarkInputRule } from '../input-rule'
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* @internal
|
|
18
|
+
*/
|
|
19
|
+
export type StrikeSpecExtension = Extension<{
|
|
20
|
+
Marks: {
|
|
21
|
+
strike: Attrs
|
|
22
|
+
}
|
|
23
|
+
}>
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* @internal
|
|
27
|
+
*/
|
|
28
|
+
export function defineStrikeSpec(): StrikeSpecExtension {
|
|
29
|
+
return defineMarkSpec({
|
|
30
|
+
name: 'strike',
|
|
31
|
+
parseDOM: [
|
|
32
|
+
{ tag: 's' },
|
|
33
|
+
{ tag: 'strike' },
|
|
34
|
+
{ tag: 'del' },
|
|
35
|
+
{ style: 'text-decoration=line-through' },
|
|
36
|
+
{ style: 'text-decoration-line=line-through' },
|
|
37
|
+
],
|
|
38
|
+
toDOM() {
|
|
39
|
+
return ['s', 0]
|
|
40
|
+
},
|
|
41
|
+
})
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* @internal
|
|
46
|
+
*/
|
|
47
|
+
export type StrikeCommandsExtension = Extension<{
|
|
48
|
+
Commands: {
|
|
49
|
+
toggleStrike: []
|
|
50
|
+
}
|
|
51
|
+
}>
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* @internal
|
|
55
|
+
*/
|
|
56
|
+
export function defineStrikeCommands(): StrikeCommandsExtension {
|
|
57
|
+
return defineCommands({
|
|
58
|
+
toggleStrike: () => toggleMark({ type: 'strike' }),
|
|
59
|
+
})
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* @internal
|
|
64
|
+
*/
|
|
65
|
+
export function defineStrikeKeymap(): PlainExtension {
|
|
66
|
+
return defineKeymap({
|
|
67
|
+
'Mod-shift-s': toggleMark({ type: 'strike' }),
|
|
68
|
+
'Mod-shift-x': toggleMark({ type: 'strike' }),
|
|
69
|
+
})
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* @internal
|
|
74
|
+
*/
|
|
75
|
+
export function defineStrikeInputRule(): PlainExtension {
|
|
76
|
+
return defineMarkInputRule({
|
|
77
|
+
regex: canUseRegexLookbehind()
|
|
78
|
+
? /(?<=\s|^)~~([^\s~]|[^\s~][^~]*[^\s~])~~$/
|
|
79
|
+
: /~~([^\s~]|[^\s~][^~]*[^\s~])~~$/,
|
|
80
|
+
type: 'strike',
|
|
81
|
+
})
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* @internal
|
|
86
|
+
*/
|
|
87
|
+
export type StrikeExtension = Union<
|
|
88
|
+
[StrikeSpecExtension, StrikeCommandsExtension]
|
|
89
|
+
>
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* @public
|
|
93
|
+
*/
|
|
94
|
+
export function defineStrike(): StrikeExtension {
|
|
95
|
+
return union(
|
|
96
|
+
defineStrikeSpec(),
|
|
97
|
+
defineStrikeCommands(),
|
|
98
|
+
defineStrikeKeymap(),
|
|
99
|
+
defineStrikeInputRule(),
|
|
100
|
+
)
|
|
101
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
export {
|
|
2
|
+
defineTable,
|
|
3
|
+
type TableExtension,
|
|
4
|
+
} from './table'
|
|
5
|
+
export {
|
|
6
|
+
defineTableCommands,
|
|
7
|
+
type TableCommandsExtension,
|
|
8
|
+
} from './table-commands'
|
|
9
|
+
export { exitTable } from './table-commands/exit-table'
|
|
10
|
+
export {
|
|
11
|
+
insertTable,
|
|
12
|
+
type InsertTableOptions,
|
|
13
|
+
} from './table-commands/insert-table'
|
|
14
|
+
export {
|
|
15
|
+
moveTableColumn,
|
|
16
|
+
type MoveTableColumnOptions,
|
|
17
|
+
} from './table-commands/move-table-column'
|
|
18
|
+
export {
|
|
19
|
+
moveTableRow,
|
|
20
|
+
type MoveTableRowOptions,
|
|
21
|
+
} from './table-commands/move-table-row'
|
|
22
|
+
export {
|
|
23
|
+
selectTable,
|
|
24
|
+
type SelectTableOptions,
|
|
25
|
+
} from './table-commands/select-table'
|
|
26
|
+
export {
|
|
27
|
+
selectTableCell,
|
|
28
|
+
type SelectTableCellOptions,
|
|
29
|
+
} from './table-commands/select-table-cell'
|
|
30
|
+
export {
|
|
31
|
+
selectTableColumn,
|
|
32
|
+
type SelectTableColumnOptions,
|
|
33
|
+
} from './table-commands/select-table-column'
|
|
34
|
+
export {
|
|
35
|
+
selectTableRow,
|
|
36
|
+
type SelectTableRowOptions,
|
|
37
|
+
} from './table-commands/select-table-row'
|
|
38
|
+
export { defineTableDropIndicator } from './table-drop-indicator'
|
|
39
|
+
export { defineTablePlugins } from './table-plugins'
|
|
40
|
+
export {
|
|
41
|
+
defineTableCellSpec,
|
|
42
|
+
defineTableHeaderCellSpec,
|
|
43
|
+
defineTableRowSpec,
|
|
44
|
+
defineTableSpec,
|
|
45
|
+
type TableCellSpecExtension,
|
|
46
|
+
type TableHeaderCellSpecExtension,
|
|
47
|
+
type TableRowSpecExtension,
|
|
48
|
+
type TableSpecExtension,
|
|
49
|
+
} from './table-spec'
|
|
50
|
+
export {
|
|
51
|
+
findTable,
|
|
52
|
+
isCellSelection,
|
|
53
|
+
} from './table-utils'
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
.ProseMirror .tableWrapper {
|
|
2
|
+
overflow-x: auto;
|
|
3
|
+
}
|
|
4
|
+
.ProseMirror table {
|
|
5
|
+
width: 100%;
|
|
6
|
+
overflow: hidden;
|
|
7
|
+
border-collapse: collapse;
|
|
8
|
+
table-layout: fixed;
|
|
9
|
+
}
|
|
10
|
+
.ProseMirror td,
|
|
11
|
+
.ProseMirror th {
|
|
12
|
+
box-sizing: border-box;
|
|
13
|
+
position: relative;
|
|
14
|
+
padding-right: 0.75rem;
|
|
15
|
+
padding-left: 0.75rem;
|
|
16
|
+
border-width: 1px;
|
|
17
|
+
vertical-align: top;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
prosekit-table-handle-drop-indicator {
|
|
21
|
+
background-color: HighlightText;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.ProseMirror .column-resize-handle {
|
|
25
|
+
z-index: 20;
|
|
26
|
+
position: absolute;
|
|
27
|
+
top: 0;
|
|
28
|
+
right: -2px;
|
|
29
|
+
bottom: 0;
|
|
30
|
+
width: 4px;
|
|
31
|
+
background-color: HighlightText;
|
|
32
|
+
pointer-events: none;
|
|
33
|
+
}
|
|
34
|
+
.ProseMirror.resize-cursor {
|
|
35
|
+
cursor: ew-resize;
|
|
36
|
+
cursor: col-resize;
|
|
37
|
+
}
|
|
38
|
+
.ProseMirror .selectedCell {
|
|
39
|
+
--color: 210, 100%, 56%;
|
|
40
|
+
border: 1px double hsl(var(--color));
|
|
41
|
+
background-color: hsla(var(--color), 20%);
|
|
42
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import {
|
|
2
|
+
describe,
|
|
3
|
+
expect,
|
|
4
|
+
it,
|
|
5
|
+
} from 'vitest'
|
|
6
|
+
|
|
7
|
+
import { setupTest } from '../../testing'
|
|
8
|
+
import { isCellSelection } from '../table-utils'
|
|
9
|
+
import { setCellSelection } from '../test-utils'
|
|
10
|
+
|
|
11
|
+
describe('deleteCellSelection', () => {
|
|
12
|
+
it('can clear the content in the selected table cells', () => {
|
|
13
|
+
const { editor, n: { doc, table, tr, td } } = setupTest()
|
|
14
|
+
const doc1 = doc(
|
|
15
|
+
table(
|
|
16
|
+
tr(/*2*/ td('1'), /*7*/ td('2') /*12*/),
|
|
17
|
+
/*13*/
|
|
18
|
+
tr(/*14*/ td('3'), /*19*/ td('4') /*24*/),
|
|
19
|
+
/*25*/
|
|
20
|
+
tr(/*26*/ td('5'), /*31*/ td('6') /*36*/),
|
|
21
|
+
),
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
editor.set(doc1)
|
|
25
|
+
editor.exec(setCellSelection(2, 19))
|
|
26
|
+
expect(isCellSelection(editor.state.selection)).toBe(true)
|
|
27
|
+
|
|
28
|
+
editor.commands.deleteCellSelection()
|
|
29
|
+
expect(isCellSelection(editor.state.selection)).toBe(true)
|
|
30
|
+
|
|
31
|
+
const doc2 = doc(
|
|
32
|
+
table(
|
|
33
|
+
//
|
|
34
|
+
tr(td(), td()),
|
|
35
|
+
tr(td(), td()),
|
|
36
|
+
tr(td('5'), td('6')),
|
|
37
|
+
),
|
|
38
|
+
)
|
|
39
|
+
expect(editor.state.doc.toJSON()).toEqual(doc2.toJSON())
|
|
40
|
+
})
|
|
41
|
+
})
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { deleteCellSelection } from 'prosemirror-tables'
|