@witchcraft/editor 0.0.6 → 0.0.8
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/module.json +1 -1
- package/dist/runtime/components/CodeBlockThemePicker.vue +0 -1
- package/dist/runtime/components/Commands.vue +1 -1
- package/dist/runtime/components/Editor.vue +1 -2
- package/dist/runtime/composables/useEditor.d.ts +1 -1
- package/dist/runtime/demo/App.vue +0 -1
- package/dist/runtime/pm/features/Blockquote/Blockquote.d.ts +1 -1
- package/dist/runtime/pm/features/Blocks/components/DragTreeHandle.d.vue.ts +26 -0
- package/dist/runtime/pm/features/Blocks/components/DragTreeHandle.vue +7 -0
- package/dist/runtime/pm/features/Blocks/components/DragTreeHandle.vue.d.ts +26 -0
- package/dist/runtime/pm/features/Blocks/components/ItemMenu.vue +1 -2
- package/dist/runtime/pm/features/Blocks/components/ItemNodeView.vue +0 -1
- package/dist/runtime/pm/features/Blocks/components/defaultItemMenu.d.ts +2 -2
- package/dist/runtime/pm/features/Blocks/composables/useNodeStates.d.ts +2 -2
- package/dist/runtime/pm/features/CodeBlock/CodeBlock.d.ts +1 -1
- package/dist/runtime/pm/features/CodeBlock/components/CodeBlockView.vue +0 -1
- package/dist/runtime/pm/features/CodeBlock/composables/useHighlightJsTheme.d.ts +3 -3
- package/dist/runtime/pm/features/CommandsMenus/components/CommandBar.vue +1 -1
- package/dist/runtime/pm/features/CommandsMenus/components/CommandBarItem.vue +1 -1
- package/dist/runtime/pm/features/CommandsMenus/components/CommandMenuGroup.vue +0 -1
- package/dist/runtime/pm/features/CommandsMenus/icons/HighlightIcon.vue +1 -1
- package/dist/runtime/pm/features/EmbeddedDocument/components/EmbeddedDocumentPicker.vue +0 -1
- package/dist/runtime/pm/features/EmbeddedDocument/components/EmbeddedNodeView.vue +0 -1
- package/dist/runtime/pm/features/FileLoader/components/FileLoaderNodeView.vue +0 -1
- package/dist/runtime/pm/features/HardBreak/HardBreak.d.ts +1 -1
- package/dist/runtime/pm/features/Link/components/BubbleMenuExternalLink.vue +1 -1
- package/dist/runtime/pm/features/Link/components/BubbleMenuInternalLink.vue +1 -1
- package/dist/runtime/pm/features/Link/components/BubbleMenuLink.vue +1 -1
- package/dist/runtime/pm/features/Menus/components/MarkMenuManager.vue +1 -1
- package/dist/runtime/pm/features/Tables/index.d.ts +5 -5
- package/dist/runtime/pm/generator.d.ts +82 -0
- package/dist/runtime/pm/generator.js +205 -0
- package/dist/runtime/pm/testSchema.d.ts +1 -1
- package/dist/runtime/pm/utils/generateRandomDoc.d.ts +23 -0
- package/dist/runtime/pm/utils/generateRandomDoc.js +83 -0
- package/dist/runtime/pm/utils/generateRandomTree.d.ts +50 -0
- package/dist/runtime/pm/utils/generateRandomTree.js +38 -0
- package/package.json +7 -5
- package/src/module.ts +1 -0
- package/src/runtime/components/CodeBlockThemePicker.vue +0 -1
- package/src/runtime/components/Editor.vue +0 -1
- package/src/runtime/demo/App.vue +0 -1
- package/src/runtime/pm/commands/changeAttrs.ts +1 -1
- package/src/runtime/pm/features/Blocks/Item.ts +1 -1
- package/src/runtime/pm/features/Blocks/commands/moveItem.ts +1 -1
- package/src/runtime/pm/features/Blocks/components/DragTreeHandle.vue +18 -14
- package/src/runtime/pm/features/Blocks/components/ItemMenu.vue +0 -1
- package/src/runtime/pm/features/Blocks/components/ItemNodeView.vue +0 -1
- package/src/runtime/pm/features/CodeBlock/components/CodeBlockView.vue +0 -1
- package/src/runtime/pm/features/CommandsMenus/components/CommandMenuGroup.vue +0 -1
- package/src/runtime/pm/features/EmbeddedDocument/Embedded.ts +1 -1
- package/src/runtime/pm/features/EmbeddedDocument/components/EmbeddedDocumentPicker.vue +0 -1
- package/src/runtime/pm/features/EmbeddedDocument/components/EmbeddedNodeView.vue +0 -1
- package/src/runtime/pm/features/FileLoader/components/FileLoaderNodeView.vue +0 -1
- package/src/runtime/pm/features/FileLoader/types.ts +2 -2
- package/src/runtime/pm/generator.ts +266 -0
- package/src/runtime/pm/schema.ts +1 -0
- package/src/runtime/pm/utils/generateRandomDoc.ts +140 -0
- package/src/runtime/pm/utils/generateRandomTree.ts +100 -0
package/dist/module.json
CHANGED
|
@@ -46,7 +46,7 @@ import { pretty } from "@alanscodelog/utils";
|
|
|
46
46
|
import WButton from "@witchcraft/ui/components/LibButton";
|
|
47
47
|
import { twMerge } from "tailwind-merge";
|
|
48
48
|
const props = defineProps({
|
|
49
|
-
editor: { type:
|
|
49
|
+
editor: { type: Object, required: true },
|
|
50
50
|
commands: { type: Array, required: true }
|
|
51
51
|
});
|
|
52
52
|
function handlePointerDown($event, command, args) {
|
|
@@ -27,7 +27,6 @@
|
|
|
27
27
|
v-bind="$attrs"
|
|
28
28
|
>
|
|
29
29
|
<!-- The class `is-embedded-block` is not needed internally, but is added for consistency in case it might be useful. -->
|
|
30
|
-
<!-- @vue-expect-error -->
|
|
31
30
|
<editor-content
|
|
32
31
|
:editor="editor"
|
|
33
32
|
spellcheck="false"
|
|
@@ -80,7 +79,7 @@ import MarkMenuManager from "../pm/features/Menus/components/MarkMenuManager.vue
|
|
|
80
79
|
import { extensions } from "../pm/schema.js";
|
|
81
80
|
import { menusInjectionKey } from "../types/index.js";
|
|
82
81
|
const props = defineProps({
|
|
83
|
-
content: { type: null, required: false, default: void 0 },
|
|
82
|
+
content: { type: [String, Object, Array, null], required: false, default: void 0 },
|
|
84
83
|
docId: { type: String, required: false, default: void 0 },
|
|
85
84
|
documentApi: { type: null, required: false, default: void 0 },
|
|
86
85
|
linkOptions: { type: Object, required: false, default: void 0 },
|
|
@@ -4,6 +4,6 @@ import { Editor } from "@tiptap/vue-3";
|
|
|
4
4
|
* Unline tiptap's useEditor, this does not auto-mount the editor. Instead the returned `recreate` function must be called manually. This was built with the use of {@link useContentEditor} in mind.
|
|
5
5
|
*/
|
|
6
6
|
export declare const useEditor: (options?: Partial<EditorOptions>) => {
|
|
7
|
-
editor: import("
|
|
7
|
+
editor: import("vue").ShallowRef<Editor | undefined, Editor | undefined>;
|
|
8
8
|
recreate: (modifyOptions?: (options: Partial<EditorOptions>) => Partial<EditorOptions>) => void;
|
|
9
9
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Node } from "@tiptap/core";
|
|
2
|
-
export declare const Blockquote: Node<import("@tiptap/extension-blockquote"
|
|
2
|
+
export declare const Blockquote: Node<import("@tiptap/extension-blockquote").BlockquoteOptions, any>;
|
|
3
3
|
export type NodeBlockquoteName = "blockquote";
|
|
4
4
|
export declare const Cite: Node<any, any>;
|
|
5
5
|
export type NodeCiteName = "cite";
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Multipurpose drag handle + collapse indicator.
|
|
3
|
+
*
|
|
4
|
+
* This is incredibly useful for making a compact draggable tree view.
|
|
5
|
+
*
|
|
6
|
+
* The collapse indicator has a default height, but it should be set manually. For example `[&>.collapse-indicator]:h-[...]`
|
|
7
|
+
*
|
|
8
|
+
* The component only emits a few events, it does not handle the dragging itself or what actually happens on any clicks/input.
|
|
9
|
+
*/
|
|
10
|
+
interface Props {
|
|
11
|
+
hasChildren: boolean;
|
|
12
|
+
passedDragThreshold: boolean;
|
|
13
|
+
hideChildren: boolean;
|
|
14
|
+
}
|
|
15
|
+
declare const _default: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
16
|
+
collapseIndicatorClick: (event: MouseEvent) => any;
|
|
17
|
+
grabHandlePassiveTouchStart: (event: TouchEvent) => any;
|
|
18
|
+
grabHandlePointerDown: (event: PointerEvent) => any;
|
|
19
|
+
grabHandleContextMenu: (event: PointerEvent) => any;
|
|
20
|
+
}, string, import("vue").PublicProps, Readonly<Props> & Readonly<{
|
|
21
|
+
onCollapseIndicatorClick?: ((event: MouseEvent) => any) | undefined;
|
|
22
|
+
onGrabHandlePassiveTouchStart?: ((event: TouchEvent) => any) | undefined;
|
|
23
|
+
onGrabHandlePointerDown?: ((event: PointerEvent) => any) | undefined;
|
|
24
|
+
onGrabHandleContextMenu?: ((event: PointerEvent) => any) | undefined;
|
|
25
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
26
|
+
export default _default;
|
|
@@ -99,9 +99,16 @@
|
|
|
99
99
|
</div>
|
|
100
100
|
</template>
|
|
101
101
|
|
|
102
|
+
<script>
|
|
103
|
+
|
|
104
|
+
</script>
|
|
105
|
+
|
|
102
106
|
<script setup>
|
|
103
107
|
import { twMerge } from "@witchcraft/ui/utils/twMerge";
|
|
104
108
|
import { onMounted, onUnmounted, ref, useAttrs } from "vue";
|
|
109
|
+
defineOptions({
|
|
110
|
+
name: "DragTreeHandle"
|
|
111
|
+
});
|
|
105
112
|
const $attrs = useAttrs();
|
|
106
113
|
defineProps({
|
|
107
114
|
hasChildren: { type: Boolean, required: true },
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Multipurpose drag handle + collapse indicator.
|
|
3
|
+
*
|
|
4
|
+
* This is incredibly useful for making a compact draggable tree view.
|
|
5
|
+
*
|
|
6
|
+
* The collapse indicator has a default height, but it should be set manually. For example `[&>.collapse-indicator]:h-[...]`
|
|
7
|
+
*
|
|
8
|
+
* The component only emits a few events, it does not handle the dragging itself or what actually happens on any clicks/input.
|
|
9
|
+
*/
|
|
10
|
+
interface Props {
|
|
11
|
+
hasChildren: boolean;
|
|
12
|
+
passedDragThreshold: boolean;
|
|
13
|
+
hideChildren: boolean;
|
|
14
|
+
}
|
|
15
|
+
declare const _default: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
16
|
+
collapseIndicatorClick: (event: MouseEvent) => any;
|
|
17
|
+
grabHandlePassiveTouchStart: (event: TouchEvent) => any;
|
|
18
|
+
grabHandlePointerDown: (event: PointerEvent) => any;
|
|
19
|
+
grabHandleContextMenu: (event: PointerEvent) => any;
|
|
20
|
+
}, string, import("vue").PublicProps, Readonly<Props> & Readonly<{
|
|
21
|
+
onCollapseIndicatorClick?: ((event: MouseEvent) => any) | undefined;
|
|
22
|
+
onGrabHandlePassiveTouchStart?: ((event: TouchEvent) => any) | undefined;
|
|
23
|
+
onGrabHandlePointerDown?: ((event: PointerEvent) => any) | undefined;
|
|
24
|
+
onGrabHandleContextMenu?: ((event: PointerEvent) => any) | undefined;
|
|
25
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
26
|
+
export default _default;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<!-- @vue-expect-error -->
|
|
3
2
|
<WPopup
|
|
4
3
|
:model-value="menu.opened"
|
|
5
4
|
:preferred-horizontal="['left-most']"
|
|
@@ -33,7 +32,7 @@ import { popupVerticalPositioner } from "../../CommandsMenus/utils/popupVertical
|
|
|
33
32
|
import { itemMenuPluginKey } from "../types.js";
|
|
34
33
|
import { createItemMenuCommandExecuter } from "../utils/createItemMenuCommandExecuter.js";
|
|
35
34
|
const props = defineProps({
|
|
36
|
-
editor: { type:
|
|
35
|
+
editor: { type: Object, required: true }
|
|
37
36
|
});
|
|
38
37
|
const menu = ref({ opened: false, id: void 0 });
|
|
39
38
|
const popup = ref();
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export declare const defaultItemMenu: (import("../types.
|
|
1
|
+
export declare const defaultItemMenu: (import("../types.js").ItemMenuCommand | {
|
|
2
2
|
type: "group";
|
|
3
3
|
title: string;
|
|
4
|
-
variations: import("../types.
|
|
4
|
+
variations: import("../types.js").ItemMenuCommand[];
|
|
5
5
|
})[];
|
|
@@ -2,6 +2,6 @@ import type { Node } from "@tiptap/pm/model";
|
|
|
2
2
|
export declare function useNodeStates(props: {
|
|
3
3
|
node: Node;
|
|
4
4
|
}): {
|
|
5
|
-
counterStyle: import("
|
|
6
|
-
nodeState: import("
|
|
5
|
+
counterStyle: import("vue").ComputedRef<string>;
|
|
6
|
+
nodeState: import("vue").ComputedRef<import("../types.js").StatefulNodeStateEntry<string> | undefined>;
|
|
7
7
|
};
|
|
@@ -12,5 +12,5 @@ export declare const lowlightInstance: {
|
|
|
12
12
|
};
|
|
13
13
|
registered: (aliasOrName: string) => boolean;
|
|
14
14
|
};
|
|
15
|
-
export declare const CodeBlock: import("@tiptap/core").Node<import("@tiptap/extension-code-block-lowlight"
|
|
15
|
+
export declare const CodeBlock: import("@tiptap/core").Node<import("@tiptap/extension-code-block-lowlight").CodeBlockLowlightOptions, any>;
|
|
16
16
|
export type NodeCodeBlockName = "codeBlock";
|
|
@@ -30,8 +30,8 @@ export declare function useHighlightJsTheme({ defaultTheme, darkLightBgs, additi
|
|
|
30
30
|
theme: Ref<string, string>;
|
|
31
31
|
knownThemes: Ref<string[], string[]>;
|
|
32
32
|
loadTheme: (themeName: string) => Promise<undefined | Error>;
|
|
33
|
-
isDark: import("
|
|
34
|
-
backgroundColor: import("
|
|
35
|
-
themeCss: import("
|
|
33
|
+
isDark: import("vue").ComputedRef<boolean>;
|
|
34
|
+
backgroundColor: import("vue").ComputedRef<string>;
|
|
35
|
+
themeCss: import("vue").ComputedRef<string[]>;
|
|
36
36
|
rawThemeCss: Ref<string, string>;
|
|
37
37
|
};
|
|
@@ -29,7 +29,7 @@ import { commandExecuterInjectionKey } from "../types.js";
|
|
|
29
29
|
import { defaultCommandExecuter } from "../utils/defaultCommandExecutor";
|
|
30
30
|
const props = defineProps({
|
|
31
31
|
item: { type: null, required: true },
|
|
32
|
-
editor: { type:
|
|
32
|
+
editor: { type: Object, required: true }
|
|
33
33
|
});
|
|
34
34
|
const emit = defineEmits(["close"]);
|
|
35
35
|
const executer = inject(commandExecuterInjectionKey, defaultCommandExecuter);
|
|
@@ -32,7 +32,7 @@ import { computed } from "vue";
|
|
|
32
32
|
import FaSolidHighlighter from "~icons/lucide/highlighter";
|
|
33
33
|
import { highlightPluginKey } from "../../Highlight/types.js";
|
|
34
34
|
const props = defineProps({
|
|
35
|
-
editor: { type:
|
|
35
|
+
editor: { type: Object, required: true },
|
|
36
36
|
colorSlot: { type: null, required: false }
|
|
37
37
|
});
|
|
38
38
|
const color = computed(() => {
|
|
@@ -2,4 +2,4 @@
|
|
|
2
2
|
* Extends the tiptap hard break extension to set the linebreakReplacement option (which tiptap does not expose).
|
|
3
3
|
* This option tells prosemirror that when converting between blocks that can/can't show whitespace, it should use this node type to represent line breaks in node types that don't display them.
|
|
4
4
|
*/
|
|
5
|
-
export declare const HardBreak: import("@tiptap/core").Node<import("@tiptap/extension-hard-break"
|
|
5
|
+
export declare const HardBreak: import("@tiptap/core").Node<import("@tiptap/extension-hard-break").HardBreakOptions, any>;
|
|
@@ -83,7 +83,7 @@ import iFaSolidExternalLinkAlt from "~icons/fa-solid/external-link-alt";
|
|
|
83
83
|
import iIcRoundLink from "~icons/ic/round-link";
|
|
84
84
|
import iIcRoundShortText from "~icons/ic/round-short-text";
|
|
85
85
|
const props = defineProps({
|
|
86
|
-
editor: { type:
|
|
86
|
+
editor: { type: Object, required: true },
|
|
87
87
|
linkSuggestions: { type: Array, required: false },
|
|
88
88
|
linkMark: { type: null, required: true },
|
|
89
89
|
isChanged: { type: Boolean, required: true }
|
|
@@ -56,7 +56,7 @@ import { ref, watch } from "vue";
|
|
|
56
56
|
import BubbleMenuLinkActions from "./BubbleMenuLinkActions.vue";
|
|
57
57
|
import iIcRoundLink from "~icons/ic/round-link";
|
|
58
58
|
const props = defineProps({
|
|
59
|
-
editor: { type:
|
|
59
|
+
editor: { type: Object, required: true },
|
|
60
60
|
linkSuggestions: { type: Array, required: false },
|
|
61
61
|
linkMark: { type: null, required: true },
|
|
62
62
|
isChanged: { type: Boolean, required: true },
|
|
@@ -53,7 +53,7 @@ import { getMarkPosition } from "../../../utils/getMarkPosition.js";
|
|
|
53
53
|
import { getMarksInSelection } from "../../../utils/getMarksInSelection.js";
|
|
54
54
|
import { linkMenuPluginKey } from "../types.js";
|
|
55
55
|
const props = defineProps({
|
|
56
|
-
editor: { type:
|
|
56
|
+
editor: { type: Object, required: true },
|
|
57
57
|
linkSuggestions: { type: Array, required: false },
|
|
58
58
|
internalLinkSuggestions: { type: Array, required: false },
|
|
59
59
|
getLinkSuggestions: { type: Function, required: false },
|
|
@@ -47,7 +47,7 @@ import {
|
|
|
47
47
|
import { findUpwards } from "../../../utils/findUpwards.js";
|
|
48
48
|
import { menusInjectionKey, menusPluginKey } from "../types.js";
|
|
49
49
|
const props = defineProps({
|
|
50
|
-
editor: { type:
|
|
50
|
+
editor: { type: Object, required: true }
|
|
51
51
|
});
|
|
52
52
|
const menus = inject(menusInjectionKey, ref({}));
|
|
53
53
|
const activeMarkMenu = ref();
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
export declare const TableRow: import("@tiptap/core").Node<import("@tiptap/extension-table"
|
|
2
|
-
export declare const TableCell: import("@tiptap/core").Node<import("@tiptap/extension-table"
|
|
3
|
-
export declare const TableHeader: import("@tiptap/core").Node<import("@tiptap/extension-table"
|
|
4
|
-
export declare const Table: import("@tiptap/core").Node<import("@tiptap/extension-table"
|
|
5
|
-
export declare const TableExtensions: (import("@tiptap/core").Node<import("@tiptap/extension-table"
|
|
1
|
+
export declare const TableRow: import("@tiptap/core").Node<import("@tiptap/extension-table").TableRowOptions, any>;
|
|
2
|
+
export declare const TableCell: import("@tiptap/core").Node<import("@tiptap/extension-table").TableCellOptions, any>;
|
|
3
|
+
export declare const TableHeader: import("@tiptap/core").Node<import("@tiptap/extension-table").TableHeaderOptions, any>;
|
|
4
|
+
export declare const Table: import("@tiptap/core").Node<import("@tiptap/extension-table").TableOptions, any>;
|
|
5
|
+
export declare const TableExtensions: (import("@tiptap/core").Node<import("@tiptap/extension-table").TableRowOptions, any> | import("@tiptap/core").Node<import("@tiptap/extension-table").TableOptions, any>)[];
|
|
6
6
|
export type NodeTableName = "table";
|
|
7
7
|
export type NodeTableRowName = "tableRow";
|
|
8
8
|
export type NodeTableCellName = "tableCell";
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import type { Mark, Node } from "@tiptap/pm/model";
|
|
2
|
+
export declare const pm: {
|
|
3
|
+
schema: import("@tiptap/pm/model").Schema<"paragraph" | "item" | "codeBlock" | "heading" | "iframe" | "image" | "table" | "text" | "blockquote" | "cite" | "list" | "tableCell" | "doc" | "embeddedDoc" | "tableRow" | "tableHeader", "bold" | "code" | "italic" | "strike" | "subscript" | "superscript" | "underline" | "hardBreak" | "highlight">;
|
|
4
|
+
} & {
|
|
5
|
+
readonly [x: string]: import("prosemirror-test-builder").NodeBuilder;
|
|
6
|
+
readonly paragraph: import("prosemirror-test-builder").NodeBuilder;
|
|
7
|
+
readonly item: import("prosemirror-test-builder").NodeBuilder;
|
|
8
|
+
readonly codeBlock: import("prosemirror-test-builder").NodeBuilder;
|
|
9
|
+
readonly heading: import("prosemirror-test-builder").NodeBuilder;
|
|
10
|
+
readonly iframe: import("prosemirror-test-builder").NodeBuilder;
|
|
11
|
+
readonly image: import("prosemirror-test-builder").NodeBuilder;
|
|
12
|
+
readonly table: import("prosemirror-test-builder").NodeBuilder;
|
|
13
|
+
readonly text: import("prosemirror-test-builder").NodeBuilder;
|
|
14
|
+
readonly blockquote: import("prosemirror-test-builder").NodeBuilder;
|
|
15
|
+
readonly cite: import("prosemirror-test-builder").NodeBuilder;
|
|
16
|
+
readonly list: import("prosemirror-test-builder").NodeBuilder;
|
|
17
|
+
readonly tableCell: import("prosemirror-test-builder").NodeBuilder;
|
|
18
|
+
readonly doc: import("prosemirror-test-builder").NodeBuilder;
|
|
19
|
+
readonly embeddedDoc: import("prosemirror-test-builder").NodeBuilder;
|
|
20
|
+
readonly tableRow: import("prosemirror-test-builder").NodeBuilder;
|
|
21
|
+
readonly tableHeader: import("prosemirror-test-builder").NodeBuilder;
|
|
22
|
+
} & {
|
|
23
|
+
readonly [x: string]: import("prosemirror-test-builder").MarkBuilder;
|
|
24
|
+
readonly bold: import("prosemirror-test-builder").MarkBuilder;
|
|
25
|
+
readonly code: import("prosemirror-test-builder").MarkBuilder;
|
|
26
|
+
readonly italic: import("prosemirror-test-builder").MarkBuilder;
|
|
27
|
+
readonly strike: import("prosemirror-test-builder").MarkBuilder;
|
|
28
|
+
readonly subscript: import("prosemirror-test-builder").MarkBuilder;
|
|
29
|
+
readonly superscript: import("prosemirror-test-builder").MarkBuilder;
|
|
30
|
+
readonly underline: import("prosemirror-test-builder").MarkBuilder;
|
|
31
|
+
readonly hardBreak: import("prosemirror-test-builder").MarkBuilder;
|
|
32
|
+
readonly highlight: import("prosemirror-test-builder").MarkBuilder;
|
|
33
|
+
} & {
|
|
34
|
+
[name: string]: import("prosemirror-test-builder").NodeBuilder | import("prosemirror-test-builder").MarkBuilder;
|
|
35
|
+
};
|
|
36
|
+
export type GeneratorConfigEntry<TChildrenType extends "node" | "text" = "node" | "text", TParentType extends "node" | "text" = "node" | "text", TChildren extends TChildrenType extends "node" ? Node : Mark | string = TChildrenType extends "node" ? Node : Mark | string, TParent extends TParentType extends "node" ? Node : Mark | string = TParentType extends "node" ? Node : Mark | string> = {
|
|
37
|
+
parents: {
|
|
38
|
+
/**
|
|
39
|
+
* The type of the parent (node or "text") where "text" is a string or mark.
|
|
40
|
+
* Determines the call signature of the create function.
|
|
41
|
+
*/
|
|
42
|
+
type: TParentType;
|
|
43
|
+
/** Possible parent nodes that can have the given children. The children need not be direct descendants, see `ignoreValidation`. */
|
|
44
|
+
names: string[];
|
|
45
|
+
};
|
|
46
|
+
children: {
|
|
47
|
+
/**
|
|
48
|
+
* The type of children (node or "text") where "text" is a string or mark.
|
|
49
|
+
* Determines the call signature of the create function.
|
|
50
|
+
*/
|
|
51
|
+
type: TChildrenType;
|
|
52
|
+
names?: string[];
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* Set to true to ignore all children mismatches, or set an array of children names to ignore.
|
|
56
|
+
*
|
|
57
|
+
* This is needed for creating "end" nodes that aren't valid names (e.g. `text` is not technically allowed since you can't do `builder.text()`).
|
|
58
|
+
*
|
|
59
|
+
* Or when the children are not direct children of the parent types as there is some in-between wrapper node that needs to be generated.
|
|
60
|
+
*/
|
|
61
|
+
ignoreValidation?: boolean | string[];
|
|
62
|
+
isRoot?: boolean;
|
|
63
|
+
/**
|
|
64
|
+
* Creates the node. Can return undefined to "terminate" the branch being created, the node will be filtered out of the nodes passed to it's parent.
|
|
65
|
+
*
|
|
66
|
+
* If not set, a default `builder[parentType]({}, ...children)` will be used.
|
|
67
|
+
*
|
|
68
|
+
* Note also, it is not required to use the children. You can ignore them or use a subset or create a different one if needed (some node types *require* text and if your text not can return "" this can be a problem).
|
|
69
|
+
*/
|
|
70
|
+
create?: (parent: string, children: TChildren[]) => TParent | undefined;
|
|
71
|
+
};
|
|
72
|
+
export declare function getTextOrMarkLength(textOrMark: string | Mark): number;
|
|
73
|
+
export declare function createGeneratorConfig<TChildrenType extends "node" | "text" = "node" | "text", TParentType extends "node" | "text" = "node" | "text", TChildren extends TChildrenType extends "node" ? Node : Mark | string = TChildrenType extends "node" ? Node : Mark | string, TParent extends TParentType extends "node" ? Node : Mark | string = TParentType extends "node" ? Node : Mark | string>(config: GeneratorConfigEntry<TChildrenType, TParentType, TChildren, TParent>): GeneratorConfigEntry<TChildrenType, TParentType, TChildren, TParent>;
|
|
74
|
+
export declare const generatorConfig: (GeneratorConfigEntry<"node", "node", Node, Node & {
|
|
75
|
+
tag: {
|
|
76
|
+
[tag: string]: number;
|
|
77
|
+
};
|
|
78
|
+
}> | GeneratorConfigEntry<"text", "node", string | Mark, Node & {
|
|
79
|
+
tag: {
|
|
80
|
+
[tag: string]: number;
|
|
81
|
+
};
|
|
82
|
+
}> | GeneratorConfigEntry<"text", "text", string | Mark, string | Mark>)[];
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
import { faker } from "@faker-js/faker";
|
|
2
|
+
import { nanoid } from "nanoid";
|
|
3
|
+
import { builders } from "prosemirror-test-builder";
|
|
4
|
+
import { schema } from "./schema.js";
|
|
5
|
+
export const pm = builders(schema);
|
|
6
|
+
export function getTextOrMarkLength(textOrMark) {
|
|
7
|
+
if (typeof textOrMark === "string") {
|
|
8
|
+
return textOrMark.length;
|
|
9
|
+
}
|
|
10
|
+
const textNodes = textOrMark.flat.map((_) => "text" in _ ? _.text.length : getTextOrMarkLength(_));
|
|
11
|
+
return textNodes.reduce((a, b) => a + b, 0);
|
|
12
|
+
}
|
|
13
|
+
export function createGeneratorConfig(config) {
|
|
14
|
+
return config;
|
|
15
|
+
}
|
|
16
|
+
function createPsuedoSentence() {
|
|
17
|
+
const sentenceLength = faker.number.int({ min: 0, max: 1e3 });
|
|
18
|
+
const sentence = Array.from(
|
|
19
|
+
{ length: sentenceLength },
|
|
20
|
+
() => faker.string.sample({ min: 0, max: 1e3 })
|
|
21
|
+
).join(" ");
|
|
22
|
+
return sentence;
|
|
23
|
+
}
|
|
24
|
+
export const generatorConfig = [
|
|
25
|
+
createGeneratorConfig({
|
|
26
|
+
isRoot: true,
|
|
27
|
+
parents: { type: "node", names: ["doc"] },
|
|
28
|
+
ignoreValidation: true,
|
|
29
|
+
children: { type: "node", names: ["item"] },
|
|
30
|
+
create: (_parent, children) => {
|
|
31
|
+
if (!children || children.length === 0) {
|
|
32
|
+
return pm.doc(pm.list(pm.item({ blockId: nanoid(10) }, pm.paragraph({}, ""))));
|
|
33
|
+
}
|
|
34
|
+
return pm.doc(pm.list(...children));
|
|
35
|
+
}
|
|
36
|
+
}),
|
|
37
|
+
createGeneratorConfig({
|
|
38
|
+
parents: { type: "node", names: ["list"] },
|
|
39
|
+
children: { type: "node", names: ["item"] },
|
|
40
|
+
create: (_parent, children) => {
|
|
41
|
+
if (!children || children.length === 0) {
|
|
42
|
+
return pm.list(pm.item({ blockId: nanoid(10) }, pm.paragraph("")));
|
|
43
|
+
}
|
|
44
|
+
return pm.list(...children);
|
|
45
|
+
}
|
|
46
|
+
}),
|
|
47
|
+
createGeneratorConfig({
|
|
48
|
+
parents: { type: "node", names: ["item"] },
|
|
49
|
+
children: { type: "node", names: [
|
|
50
|
+
"paragraph",
|
|
51
|
+
"heading",
|
|
52
|
+
"codeBlock",
|
|
53
|
+
"embeddedDoc",
|
|
54
|
+
"iframe",
|
|
55
|
+
"table",
|
|
56
|
+
"image",
|
|
57
|
+
"blockquote"
|
|
58
|
+
] },
|
|
59
|
+
create: (_parent, children) => {
|
|
60
|
+
if (!children || children.length === 0) {
|
|
61
|
+
return pm.item({ blockId: nanoid(10) }, pm.paragraph(""));
|
|
62
|
+
}
|
|
63
|
+
return pm.item(
|
|
64
|
+
{ blockId: nanoid(10) },
|
|
65
|
+
children[0],
|
|
66
|
+
...children.length > 1 ? [pm.list(
|
|
67
|
+
{},
|
|
68
|
+
...children.slice(1).map(
|
|
69
|
+
(_) => pm.item({ blockId: nanoid(10) }, _)
|
|
70
|
+
)
|
|
71
|
+
)] : []
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
}),
|
|
75
|
+
createGeneratorConfig({
|
|
76
|
+
parents: { type: "node", names: ["blockquote"] },
|
|
77
|
+
children: { type: "node", names: ["paragraph", "cite"] },
|
|
78
|
+
create: (_parent, children) => {
|
|
79
|
+
const parTypes = [];
|
|
80
|
+
const citeTypes = [];
|
|
81
|
+
for (const child of children) {
|
|
82
|
+
if (child.type.name === "cite") {
|
|
83
|
+
citeTypes.push(child);
|
|
84
|
+
} else {
|
|
85
|
+
parTypes.push(child);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
if (parTypes.length === 0) {
|
|
89
|
+
return pm.blockquote({}, pm.paragraph(""));
|
|
90
|
+
} else {
|
|
91
|
+
const someCite = citeTypes.find((_) => _.textContent.length > 0) ?? pm.cite({}, createPsuedoSentence());
|
|
92
|
+
return pm.blockquote({}, ...parTypes, someCite);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}),
|
|
96
|
+
createGeneratorConfig({
|
|
97
|
+
parents: { type: "node", names: ["table"] },
|
|
98
|
+
children: { type: "node", names: [
|
|
99
|
+
"tableHeader",
|
|
100
|
+
"tableCell"
|
|
101
|
+
] },
|
|
102
|
+
ignoreValidation: true,
|
|
103
|
+
// we're handling the in-between tableRow nodes
|
|
104
|
+
create: (_parent, children) => {
|
|
105
|
+
const headerType = [];
|
|
106
|
+
const cellType = [];
|
|
107
|
+
for (const child of children) {
|
|
108
|
+
if (child.type.name === "tableHeader") {
|
|
109
|
+
headerType.push(child);
|
|
110
|
+
} else if (child.type.name === "tableCell") {
|
|
111
|
+
cellType.push(child);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
const colNum = headerType.length;
|
|
115
|
+
if (colNum === 0) {
|
|
116
|
+
return pm.table({}, pm.tableRow({}, pm.tableCell(pm.paragraph(""))));
|
|
117
|
+
}
|
|
118
|
+
const rowCount = Math.ceil(cellType.length / colNum);
|
|
119
|
+
const rows = [];
|
|
120
|
+
for (let i = 0; i < rowCount; i++) {
|
|
121
|
+
rows.push(pm.tableRow({}, ...cellType.slice(i * colNum, (i + 1) * colNum)));
|
|
122
|
+
}
|
|
123
|
+
return pm.table({}, pm.tableRow({}, ...headerType), ...rows);
|
|
124
|
+
}
|
|
125
|
+
}),
|
|
126
|
+
createGeneratorConfig({
|
|
127
|
+
parents: { type: "node", names: ["tableHeader", "tableCell"] },
|
|
128
|
+
children: { type: "node", names: ["paragraph"] },
|
|
129
|
+
create: (_parent, children) => {
|
|
130
|
+
if (!children || children.length === 0) {
|
|
131
|
+
return pm.tableCell(pm.paragraph(""));
|
|
132
|
+
}
|
|
133
|
+
return pm.tableCell(...children.slice(0, 1));
|
|
134
|
+
}
|
|
135
|
+
}),
|
|
136
|
+
createGeneratorConfig({
|
|
137
|
+
parents: { type: "node", names: ["paragraph", "heading", "codeBlock", "cite", "heading"] },
|
|
138
|
+
children: { type: "text", names: [
|
|
139
|
+
"bold",
|
|
140
|
+
"italic",
|
|
141
|
+
"underline",
|
|
142
|
+
"strike",
|
|
143
|
+
"subscript",
|
|
144
|
+
"superscript",
|
|
145
|
+
"code",
|
|
146
|
+
"link"
|
|
147
|
+
] },
|
|
148
|
+
create(parent, children) {
|
|
149
|
+
if (parent === "heading") {
|
|
150
|
+
return pm[parent]({ level: 1 }, ...children);
|
|
151
|
+
}
|
|
152
|
+
if (parent === "cite") {
|
|
153
|
+
return pm[parent]({}, faker.lorem.sentence());
|
|
154
|
+
}
|
|
155
|
+
if (parent === "paragraph") {
|
|
156
|
+
const someIndex = faker.number.int({ min: 0, max: children.length });
|
|
157
|
+
children.splice(someIndex, 0, pm.hardBreak());
|
|
158
|
+
}
|
|
159
|
+
return pm[parent]({}, ...children);
|
|
160
|
+
}
|
|
161
|
+
}),
|
|
162
|
+
createGeneratorConfig({
|
|
163
|
+
parents: {
|
|
164
|
+
type: "text",
|
|
165
|
+
names: [
|
|
166
|
+
"bold",
|
|
167
|
+
"italic",
|
|
168
|
+
"underline",
|
|
169
|
+
"strike",
|
|
170
|
+
"subscript",
|
|
171
|
+
"superscript",
|
|
172
|
+
"link"
|
|
173
|
+
]
|
|
174
|
+
},
|
|
175
|
+
// note the addition of text
|
|
176
|
+
children: { type: "text", names: [
|
|
177
|
+
"bold",
|
|
178
|
+
"italic",
|
|
179
|
+
"underline",
|
|
180
|
+
"strike",
|
|
181
|
+
"subscript",
|
|
182
|
+
"superscript",
|
|
183
|
+
"link",
|
|
184
|
+
"text"
|
|
185
|
+
] },
|
|
186
|
+
ignoreValidation: ["text"]
|
|
187
|
+
// text is not a real node
|
|
188
|
+
// create: (parent, children) => {
|
|
189
|
+
// return pm[parent]({}, ...children as any) as any
|
|
190
|
+
// }
|
|
191
|
+
}),
|
|
192
|
+
createGeneratorConfig({
|
|
193
|
+
ignoreValidation: true,
|
|
194
|
+
// text is not a real node
|
|
195
|
+
parents: { type: "text", names: ["code"] },
|
|
196
|
+
children: { type: "text", names: ["text"] }
|
|
197
|
+
}),
|
|
198
|
+
createGeneratorConfig({
|
|
199
|
+
parents: { type: "text", names: ["text"] },
|
|
200
|
+
children: { type: "text" },
|
|
201
|
+
create: (_parent) => {
|
|
202
|
+
return createPsuedoSentence();
|
|
203
|
+
}
|
|
204
|
+
})
|
|
205
|
+
];
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Schema } from "@tiptap/pm/model";
|
|
2
2
|
import { type NodeFileLoaderName } from "./features/FileLoader/FileLoader.js";
|
|
3
3
|
import { type schema as baseSchema } from "./schema.js";
|
|
4
|
-
export declare const testExtensions: (import("@tiptap/core").AnyExtension | import("@tiptap/core").Node<import("./features/FileLoader/types.
|
|
4
|
+
export declare const testExtensions: (import("@tiptap/core").AnyExtension | import("@tiptap/core").Node<import("./features/FileLoader/types.js").FileLoaderExtensionOptions, any>)[];
|
|
5
5
|
export declare const testSchema: typeof baseSchema & Schema<NodeFileLoaderName & "itemNoId">;
|