@witchcraft/editor 0.0.8 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. package/dist/module.json +1 -1
  2. package/dist/module.mjs +2 -2
  3. package/dist/runtime/components/CodeBlockThemePicker.d.vue.ts +4 -2
  4. package/dist/runtime/components/CodeBlockThemePicker.vue +0 -1
  5. package/dist/runtime/components/CodeBlockThemePicker.vue.d.ts +4 -2
  6. package/dist/runtime/components/Commands.d.vue.ts +2 -1
  7. package/dist/runtime/components/Commands.vue.d.ts +2 -1
  8. package/dist/runtime/components/Editor.d.vue.ts +3 -12
  9. package/dist/runtime/components/Editor.vue.d.ts +3 -12
  10. package/dist/runtime/components/EditorDemoApp.d.vue.ts +2 -1
  11. package/dist/runtime/components/EditorDemoApp.vue.d.ts +2 -1
  12. package/dist/runtime/components/EditorDemoControls.d.vue.ts +4 -2
  13. package/dist/runtime/components/EditorDemoControls.vue.d.ts +4 -2
  14. package/dist/runtime/components/TestWrapper.d.vue.ts +2 -1
  15. package/dist/runtime/components/TestWrapper.vue.d.ts +2 -1
  16. package/dist/runtime/demo/App.d.vue.ts +2 -1
  17. package/dist/runtime/demo/App.vue.d.ts +2 -1
  18. package/dist/runtime/pm/features/Blocks/components/DragTreeHandle.d.vue.ts +2 -1
  19. package/dist/runtime/pm/features/Blocks/components/DragTreeHandle.vue.d.ts +2 -1
  20. package/dist/runtime/pm/features/Blocks/components/ItemMenu.d.vue.ts +2 -1
  21. package/dist/runtime/pm/features/Blocks/components/ItemMenu.vue.d.ts +2 -1
  22. package/dist/runtime/pm/features/Blocks/components/ItemNodeView.d.vue.ts +2 -1
  23. package/dist/runtime/pm/features/Blocks/components/ItemNodeView.vue.d.ts +2 -1
  24. package/dist/runtime/pm/features/CodeBlock/components/CodeBlockView.d.vue.ts +2 -1
  25. package/dist/runtime/pm/features/CodeBlock/components/CodeBlockView.vue.d.ts +2 -1
  26. package/dist/runtime/pm/features/CommandsMenus/components/CommandBar.d.vue.ts +2 -1
  27. package/dist/runtime/pm/features/CommandsMenus/components/CommandBar.vue.d.ts +2 -1
  28. package/dist/runtime/pm/features/CommandsMenus/components/CommandBarItem.d.vue.ts +2 -1
  29. package/dist/runtime/pm/features/CommandsMenus/components/CommandBarItem.vue.d.ts +2 -1
  30. package/dist/runtime/pm/features/CommandsMenus/components/CommandMenuGroup.d.vue.ts +2 -1
  31. package/dist/runtime/pm/features/CommandsMenus/components/CommandMenuGroup.vue.d.ts +2 -1
  32. package/dist/runtime/pm/features/CommandsMenus/components/CommandMenuItem.d.vue.ts +2 -1
  33. package/dist/runtime/pm/features/CommandsMenus/components/CommandMenuItem.vue.d.ts +2 -1
  34. package/dist/runtime/pm/features/CommandsMenus/components/CommandMenuList.d.vue.ts +2 -1
  35. package/dist/runtime/pm/features/CommandsMenus/components/CommandMenuList.vue.d.ts +2 -1
  36. package/dist/runtime/pm/features/CommandsMenus/components/TextIcon.d.vue.ts +2 -1
  37. package/dist/runtime/pm/features/CommandsMenus/components/TextIcon.vue.d.ts +2 -1
  38. package/dist/runtime/pm/features/CommandsMenus/icons/HighlightIcon.d.vue.ts +2 -1
  39. package/dist/runtime/pm/features/CommandsMenus/icons/HighlightIcon.vue.d.ts +2 -1
  40. package/dist/runtime/pm/features/CommandsMenus/icons/SubscriptIcon.d.vue.ts +2 -1
  41. package/dist/runtime/pm/features/CommandsMenus/icons/SubscriptIcon.vue.d.ts +2 -1
  42. package/dist/runtime/pm/features/CommandsMenus/icons/SuperscriptIcon.d.vue.ts +2 -1
  43. package/dist/runtime/pm/features/CommandsMenus/icons/SuperscriptIcon.vue.d.ts +2 -1
  44. package/dist/runtime/pm/features/DocumentApi/DocumentApi.d.ts +3 -0
  45. package/dist/runtime/pm/features/DocumentApi/DocumentApi.js +2 -0
  46. package/dist/runtime/pm/features/DocumentApi/composables/useTestDocumentApi.js +4 -1
  47. package/dist/runtime/pm/features/EmbeddedDocument/components/EmbeddedDocumentPicker.d.vue.ts +2 -1
  48. package/dist/runtime/pm/features/EmbeddedDocument/components/EmbeddedDocumentPicker.vue +3 -3
  49. package/dist/runtime/pm/features/EmbeddedDocument/components/EmbeddedDocumentPicker.vue.d.ts +2 -1
  50. package/dist/runtime/pm/features/EmbeddedDocument/components/EmbeddedNodeView.d.vue.ts +2 -1
  51. package/dist/runtime/pm/features/EmbeddedDocument/components/EmbeddedNodeView.vue.d.ts +2 -1
  52. package/dist/runtime/pm/features/FileLoader/components/FileLoaderNodeView.d.vue.ts +2 -1
  53. package/dist/runtime/pm/features/FileLoader/components/FileLoaderNodeView.vue.d.ts +2 -1
  54. package/dist/runtime/pm/features/Iframe/components/IframeNodeView.d.vue.ts +2 -1
  55. package/dist/runtime/pm/features/Iframe/components/IframeNodeView.vue +0 -1
  56. package/dist/runtime/pm/features/Iframe/components/IframeNodeView.vue.d.ts +2 -1
  57. package/dist/runtime/pm/features/Link/components/BubbleMenuExternalLink.d.vue.ts +4 -2
  58. package/dist/runtime/pm/features/Link/components/BubbleMenuExternalLink.vue.d.ts +4 -2
  59. package/dist/runtime/pm/features/Link/components/BubbleMenuInternalLink.d.vue.ts +4 -2
  60. package/dist/runtime/pm/features/Link/components/BubbleMenuInternalLink.vue.d.ts +4 -2
  61. package/dist/runtime/pm/features/Link/components/BubbleMenuLink.d.vue.ts +2 -1
  62. package/dist/runtime/pm/features/Link/components/BubbleMenuLink.vue.d.ts +2 -1
  63. package/dist/runtime/pm/features/Link/components/BubbleMenuLinkActions.d.vue.ts +2 -1
  64. package/dist/runtime/pm/features/Link/components/BubbleMenuLinkActions.vue.d.ts +2 -1
  65. package/dist/runtime/pm/features/Menus/components/MarkMenuManager.d.vue.ts +2 -1
  66. package/dist/runtime/pm/features/Menus/components/MarkMenuManager.vue.d.ts +2 -1
  67. package/dist/runtime/pm/generator.d.ts +30 -44
  68. package/dist/runtime/pm/generator.js +112 -109
  69. package/dist/runtime/pm/utils/generateRandomDoc.d.ts +3 -21
  70. package/dist/runtime/pm/utils/generateRandomDoc.js +36 -77
  71. package/dist/runtime/pm/utils/generator/createGeneratorConfig.d.ts +33 -0
  72. package/dist/runtime/pm/utils/generator/createGeneratorConfig.js +3 -0
  73. package/dist/runtime/pm/utils/generator/createPsuedoSentence.d.ts +4 -0
  74. package/dist/runtime/pm/utils/generator/createPsuedoSentence.js +16 -0
  75. package/dist/runtime/pm/utils/generator/createRandomChildCountGenerator.d.ts +14 -0
  76. package/dist/runtime/pm/utils/generator/createRandomChildCountGenerator.js +16 -0
  77. package/dist/runtime/pm/utils/generator/getTextOrMarkLength.d.ts +2 -0
  78. package/dist/runtime/pm/utils/generator/getTextOrMarkLength.js +7 -0
  79. package/dist/runtime/pm/utils/generator/influenceWithDepth.d.ts +6 -0
  80. package/dist/runtime/pm/utils/generator/influenceWithDepth.js +6 -0
  81. package/dist/runtime/pm/utils/generator/sometimesZero.d.ts +13 -0
  82. package/dist/runtime/pm/utils/generator/sometimesZero.js +7 -0
  83. package/package.json +59 -58
  84. package/src/runtime/components/CodeBlockThemePicker.vue +0 -1
  85. package/src/runtime/pm/features/DocumentApi/DocumentApi.ts +3 -0
  86. package/src/runtime/pm/features/DocumentApi/composables/useTestDocumentApi.ts +2 -1
  87. package/src/runtime/pm/features/EmbeddedDocument/components/EmbeddedDocumentPicker.vue +3 -4
  88. package/src/runtime/pm/features/Iframe/components/IframeNodeView.vue +0 -1
  89. package/src/runtime/pm/generator.ts +104 -151
  90. package/src/runtime/pm/schema.ts +2 -2
  91. package/src/runtime/pm/utils/generateRandomDoc.ts +47 -124
  92. package/src/runtime/pm/utils/generator/createGeneratorConfig.ts +56 -0
  93. package/src/runtime/pm/utils/generator/createPsuedoSentence.ts +18 -0
  94. package/src/runtime/pm/utils/generator/createRandomChildCountGenerator.ts +31 -0
  95. package/src/runtime/pm/utils/generator/getTextOrMarkLength.ts +9 -0
  96. package/src/runtime/pm/utils/generator/influenceWithDepth.ts +11 -0
  97. package/src/runtime/pm/utils/generator/sometimesZero.ts +16 -0
  98. package/dist/runtime/pm/utils/generateRandomTree.d.ts +0 -50
  99. package/dist/runtime/pm/utils/generateRandomTree.js +0 -38
  100. package/src/runtime/pm/utils/generateRandomTree.ts +0 -100
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@witchcraft/editor",
3
3
  "description": "Block base prosemirror editor with partial/full editable document embeds, infinite embeds, and document uploads.",
4
- "version": "0.0.8",
4
+ "version": "0.1.0",
5
5
  "main": "./dist/runtime/main.lib.js",
6
6
  "type": "module",
7
7
  "sideEffects": false,
@@ -64,36 +64,37 @@
64
64
  "failOnWarn": false
65
65
  },
66
66
  "peerDependencies": {
67
- "@tiptap/core": "^3.4.2",
68
- "@tiptap/extension-blockquote": "^3.4.2",
69
- "@tiptap/extension-bold": "^3.4.2",
70
- "@tiptap/extension-code": "^3.4.2",
71
- "@tiptap/extension-code-block": "^3.4.2",
72
- "@tiptap/extension-code-block-lowlight": "^3.4.2",
73
- "@tiptap/extension-dropcursor": "^3.4.2",
74
- "@tiptap/extension-gapcursor": "^3.4.2",
75
- "@tiptap/extension-hard-break": "^3.4.2",
76
- "@tiptap/extension-heading": "^3.4.2",
77
- "@tiptap/extension-highlight": "^3.4.2",
78
- "@tiptap/extension-history": "^3.4.2",
79
- "@tiptap/extension-image": "^3.4.2",
80
- "@tiptap/extension-italic": "^3.4.2",
81
- "@tiptap/extension-link": "^3.4.2",
82
- "@tiptap/extension-paragraph": "^3.4.2",
83
- "@tiptap/extension-strike": "^3.4.2",
84
- "@tiptap/extension-subscript": "^3.4.2",
85
- "@tiptap/extension-superscript": "^3.4.2",
86
- "@tiptap/extension-table": "^3.4.2",
87
- "@tiptap/extension-table-cell": "^3.4.2",
88
- "@tiptap/extension-table-header": "^3.4.2",
89
- "@tiptap/extension-table-row": "^3.4.2",
90
- "@tiptap/extension-text": "^3.4.2",
91
- "@tiptap/extension-underline": "^3.4.2",
92
- "@tiptap/pm": "^3.4.2",
93
- "@tiptap/vue-3": "^3.4.2",
94
- "@witchcraft/ui": "^0.3.7",
95
- "tailwindcss": "^4.1.13",
96
- "vue": "^3.5.21"
67
+ "@tiptap/core": "^3.11.1",
68
+ "@tiptap/extension-blockquote": "^3.11.1",
69
+ "@tiptap/extension-bold": "^3.11.1",
70
+ "@tiptap/extension-code": "^3.11.1",
71
+ "@tiptap/extension-code-block": "^3.11.1",
72
+ "@tiptap/extension-code-block-lowlight": "^3.11.1",
73
+ "@tiptap/extension-dropcursor": "^3.11.1",
74
+ "@tiptap/extension-gapcursor": "^3.11.1",
75
+ "@tiptap/extension-hard-break": "^3.11.1",
76
+ "@tiptap/extension-heading": "^3.11.1",
77
+ "@tiptap/extension-highlight": "^3.11.1",
78
+ "@tiptap/extension-history": "^3.11.1",
79
+ "@tiptap/extension-image": "^3.11.1",
80
+ "@tiptap/extension-italic": "^3.11.1",
81
+ "@tiptap/extension-link": "^3.11.1",
82
+ "@tiptap/extension-paragraph": "^3.11.1",
83
+ "@tiptap/extension-strike": "^3.11.1",
84
+ "@tiptap/extension-subscript": "^3.11.1",
85
+ "@tiptap/extension-superscript": "^3.11.1",
86
+ "@tiptap/extension-table": "^3.11.1",
87
+ "@tiptap/extension-table-cell": "^3.11.1",
88
+ "@tiptap/extension-table-header": "^3.11.1",
89
+ "@tiptap/extension-table-row": "^3.11.1",
90
+ "@tiptap/extension-text": "^3.11.1",
91
+ "@tiptap/extension-underline": "^3.11.1",
92
+ "@tiptap/html": "^3.11.1",
93
+ "@tiptap/pm": "^3.11.1",
94
+ "@tiptap/vue-3": "^3.11.1",
95
+ "@witchcraft/ui": "^0.3.9",
96
+ "tailwindcss": "^4.1.17",
97
+ "vue": "^3.5.25"
97
98
  },
98
99
  "peerDependenciesMeta": {
99
100
  "@witchcraft/ui": {
@@ -109,16 +110,16 @@
109
110
  "dependencies": {
110
111
  "@alanscodelog/eslint-config": "^6.3.1",
111
112
  "@alanscodelog/utils": "^6.0.2",
112
- "@commitlint/cli": "^19.8.1",
113
+ "@commitlint/cli": "^20.1.0",
113
114
  "@faker-js/faker": "^10.0.0",
114
115
  "@fortawesome/fontawesome-svg-core": "^7.0.1",
115
116
  "@fortawesome/free-brands-svg-icons": "^7.0.1",
116
117
  "@fortawesome/free-regular-svg-icons": "^7.0.1",
117
118
  "@fortawesome/free-solid-svg-icons": "^7.0.1",
118
- "@nuxt/eslint-config": "^1.9.0",
119
- "@tiptap/html": "^3.4.2",
119
+ "@nuxt/eslint-config": "^1.11.0",
120
+ "@tiptap/html": "^3.11.1",
120
121
  "@witchcraft/nuxt-utils": "^0.3.6",
121
- "@witchcraft/ui": "^0.3.7",
122
+ "@witchcraft/ui": "^0.3.9",
122
123
  "colord": "^2.9.3",
123
124
  "defu": "^6.1.4",
124
125
  "highlight.js": "^11.11.1",
@@ -127,8 +128,8 @@
127
128
  "mime": "^4.1.0",
128
129
  "nanoid": "^5.1.5",
129
130
  "reka-ui": "^2.5.0",
130
- "tailwind-merge": "^3.3.1",
131
- "unplugin-vue-components": "^29.1.0",
131
+ "tailwind-merge": "^3.4.0",
132
+ "unplugin-vue-components": "^30.0.0",
132
133
  "uuid": "^13.0.0",
133
134
  "y-prosemirror": "^1.3.7",
134
135
  "yjs": "^13.6.27"
@@ -137,45 +138,45 @@
137
138
  "@alanscodelog/commitlint-config": "^3.1.2",
138
139
  "@alanscodelog/semantic-release-config": "^6.0.0",
139
140
  "@alanscodelog/tsconfigs": "^6.2.0",
140
- "@alanscodelog/vite-config": "^0.0.6",
141
- "@iconify/json": "^2.2.385",
142
- "@nuxt/kit": "^4.1.2",
141
+ "@alanscodelog/vite-config": "^0.0.7",
142
+ "@iconify/json": "^2.2.412",
143
+ "@nuxt/kit": "^4.2.1",
143
144
  "@nuxt/module-builder": "^1.0.2",
144
- "@nuxt/schema": "^4.1.2",
145
+ "@nuxt/schema": "^4.2.1",
145
146
  "@nuxt/types": "^2.18.1",
146
147
  "@playwright/test": "=1.56.0",
147
148
  "@rollup/plugin-dynamic-import-vars": "^2.1.5",
148
- "@tailwindcss/cli": "^4.1.13",
149
- "@tailwindcss/vite": "^4.1.13",
149
+ "@tailwindcss/cli": "^4.1.17",
150
+ "@tailwindcss/vite": "^4.1.17",
150
151
  "@testing-library/vue": "^8.1.0",
151
- "@types/node": "^24.5.1",
152
- "@vitejs/plugin-vue": "^6.0.1",
153
- "@vitest/browser": "^3.2.4",
154
- "@vitest/coverage-v8": "^3.2.4",
155
- "@witchcraft/ui": "^0.3.7",
152
+ "@types/node": "^24.10.1",
153
+ "@vitejs/plugin-vue": "^6.0.2",
154
+ "@vitest/browser-playwright": "^4.0.14",
155
+ "@vitest/coverage-v8": "^4.0.14",
156
+ "@witchcraft/ui": "^0.3.9",
156
157
  "concurrently": "^9.2.1",
157
158
  "cross-env": "^10.0.0",
158
- "eslint": "^9.38.0",
159
+ "eslint": "^9.39.1",
159
160
  "fast-glob": "^3.3.3",
160
161
  "http-server": "^14.1.1",
161
162
  "husky": "^9.1.7",
162
163
  "madge": "^8.0.0",
163
- "nuxt": "^4.1.2",
164
+ "nuxt": "^4.2.1",
164
165
  "onchange": "^7.1.0",
165
166
  "playwright": "=1.56.0",
166
167
  "playwright-core": "=1.56.0",
167
168
  "prosemirror-test-builder": "^1.1.1",
168
169
  "radix-vue": "^1.9.17",
169
- "semantic-release": "^24.2.8",
170
- "tailwindcss": "^4.1.13",
171
- "typedoc": "^0.28.13",
170
+ "semantic-release": "^25.0.2",
171
+ "tailwindcss": "^4.1.17",
172
+ "typedoc": "^0.28.15",
172
173
  "typescript": "~5.9.2",
173
174
  "unplugin-icons": "^22.3.0",
174
- "vite": "^7.1.5",
175
- "vitest": "^3.2.4",
176
- "vue": "^3.5.21",
177
- "vue-component-type-helpers": "^3.0.7",
178
- "vue-tsc": "^2.2.12"
175
+ "vite": "^7.2.4",
176
+ "vitest": "^4.0.14",
177
+ "vue": "^3.5.25",
178
+ "vue-component-type-helpers": "^3.1.5",
179
+ "vue-tsc": "^3.1.5"
179
180
  },
180
181
  "author": "Alan <alanscodelog@gmail.com>",
181
182
  "repository": "https://github.com/witchcraftjs/editor",
@@ -81,7 +81,6 @@ const codeBlocksTheme = defineModel<string>("codeBlocksTheme", { required: true
81
81
  rounded-sm
82
82
  shadow-[0_0_10px_1px]
83
83
  shadow-black/30
84
- mt-2
85
84
  max-h-[50vh]
86
85
  "
87
86
  ref="contentComponent"
@@ -60,6 +60,8 @@ export class DocumentApi<
60
60
  * The refCounter is called every time an editor loads or unloads a document. It's used to keep track of the number of editors that are using a document, and to unload it when no editors are using it.
61
61
  *
62
62
  * Note that you need not immediately unload the cached document. So long as the count is immediatly updated you can set a timeout to actually delete the cache entry (be sure to check the count it still 0 and you can delete it).
63
+ *
64
+ * Load is also passed the data property returned by the regular load function if it returns it.
63
65
  */
64
66
  private readonly _refCounter: {
65
67
  load: (docId: string, loaded: { state: EditorState, data?: T }) => void
@@ -101,6 +103,7 @@ export class DocumentApi<
101
103
  editorOptions: Partial<EditorOptions>
102
104
  getTitle?: (docId: string, blockId?: string) => string
103
105
  getSuggestions: DocumentApiInterface["getSuggestions"]
106
+ /** Load should create the editor state and return it. It can also optionally return extra data which will be passed to the refCounter's load function. */
104
107
  load: (docId: string, schema: Schema, plugins: Plugin[]) => Promise<{ state: EditorState, data?: T }>
105
108
  save?: DocumentApi["_save"]
106
109
  saveDebounce?: number
@@ -71,10 +71,11 @@ export function useTestDocumentApi(
71
71
  schema,
72
72
  plugins
73
73
  })
74
- return { state }
74
+ return { state /** , data: {...any additional data} */ }
75
75
  },
76
76
  refCounter: {
77
77
  load(docId: string, loaded) {
78
+ // loaded.data can be accessed here if we need it
78
79
  cache.value[docId] ??= { ...loaded, count: 0 }
79
80
  cache.value[docId].count++
80
81
  },
@@ -28,7 +28,7 @@
28
28
  }
29
29
  </component>
30
30
  <!-- @vue-expect-error -->
31
- <WSimpleInput
31
+ <WInputDeprecated
32
32
  placeholder="Change document."
33
33
  suggestions-class="max-h-[200px] overflow-y-auto"
34
34
  :suggestions="searchSuggestions"
@@ -49,7 +49,7 @@
49
49
  <template #suggestion-item="{ item }">
50
50
  {{ item.title }}
51
51
  </template>
52
- </WSimpleInput>
52
+ </WInputDeprecated>
53
53
  <WCheckbox v-model="embedFullDocument">
54
54
  Embed Full Document
55
55
  </WCheckbox>
@@ -112,8 +112,7 @@
112
112
  import WIcon from "@witchcraft/ui/components/Icon"
113
113
  import WButton from "@witchcraft/ui/components/LibButton"
114
114
  import WCheckbox from "@witchcraft/ui/components/LibCheckbox"
115
- import type WInputDeprecated from "@witchcraft/ui/components/LibInputDeprecated"
116
- import WSimpleInput from "@witchcraft/ui/components/LibSimpleInput"
115
+ import WInputDeprecated from "@witchcraft/ui/components/LibInputDeprecated"
117
116
  import { inject, nextTick, provide, ref, toRef, watch } from "vue"
118
117
 
119
118
  import ILineMdLoadingLoop from "~icons/line-md/loading-loop"
@@ -57,7 +57,6 @@
57
57
  :style="`aspect-ratio: ${node.attrs.aspectRatio}`"
58
58
  v-bind="node.attrs"
59
59
  />
60
- {{ Object.keys(node.attrs) }}
61
60
  </node-view-wrapper>
62
61
  </template>
63
62
 
@@ -1,5 +1,5 @@
1
1
  import { faker } from "@faker-js/faker"
2
- import type { Mark, Node } from "@tiptap/pm/model"
2
+ import type { Node } from "@tiptap/pm/model"
3
3
  import { nanoid } from "nanoid"
4
4
  import { builders } from "prosemirror-test-builder"
5
5
 
@@ -7,86 +7,21 @@ import { schema } from "./schema.js"
7
7
 
8
8
  export const pm = builders(schema)
9
9
 
10
- export type GeneratorConfigEntry<
11
- TChildrenType extends "node" | "text" = "node" | "text",
12
- TParentType extends "node" | "text" = "node" | "text",
13
- TChildren extends TChildrenType extends "node" ? Node : Mark | string = TChildrenType extends "node" ? Node : Mark | string,
14
- TParent extends TParentType extends "node" ? Node : Mark | string = TParentType extends "node" ? Node : Mark | string
15
- > = {
16
- parents: {
17
- /**
18
- * The type of the parent (node or "text") where "text" is a string or mark.
19
- * Determines the call signature of the create function.
20
- */
21
- type: TParentType
22
- /** Possible parent nodes that can have the given children. The children need not be direct descendants, see `ignoreValidation`. */
23
- names: string[]
24
- }
25
- children: {
26
- /**
27
- * The type of children (node or "text") where "text" is a string or mark.
28
- * Determines the call signature of the create function.
29
- */
30
- type: TChildrenType
31
- /* Children types to generate. */
32
- names?: string[]
33
- }
34
- /**
35
- * Set to true to ignore all children mismatches, or set an array of children names to ignore.
36
- *
37
- * 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()`).
38
- *
39
- * 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.
40
- */
41
- ignoreValidation?: boolean | string[]
42
- /* Whether the parent listed is the root node. */
43
- isRoot?: boolean
44
- /**
45
- * 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.
46
- *
47
- * If not set, a default `builder[parentType]({}, ...children)` will be used.
48
- *
49
- * 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).
50
- */
51
- create?: (parent: string, children: TChildren[]) => TParent | undefined
52
- }
53
-
54
- export function getTextOrMarkLength(textOrMark: string | Mark) {
55
- if (typeof textOrMark === "string") {
56
- return textOrMark.length
57
- }
58
- const textNodes = (textOrMark as any).flat.map((_: any) => "text" in _ ? _.text.length : getTextOrMarkLength(_ as any)) as number[]
59
- return textNodes.reduce((a, b) => a + b, 0)
60
- }
61
-
62
- export function createGeneratorConfig<
63
- TChildrenType extends "node" | "text" = "node" | "text",
64
- TParentType extends "node" | "text" = "node" | "text",
65
- TChildren extends TChildrenType extends "node" ? Node : Mark | string = TChildrenType extends "node" ? Node : Mark | string,
66
- TParent extends TParentType extends "node" ? Node : Mark | string = TParentType extends "node" ? Node : Mark | string
67
- >(
68
- config: GeneratorConfigEntry<TChildrenType, TParentType, TChildren, TParent>
69
- ): GeneratorConfigEntry<TChildrenType, TParentType, TChildren, TParent> {
70
- return config
71
- }
72
-
73
- function createPsuedoSentence() {
74
- // sentence generated with string.sample (which contains all possible chars) instead of lorem.sentence
75
- const sentenceLength = faker.number.int({ min: 0, max: 1000 })
76
- const sentence = Array.from(
77
- { length: sentenceLength },
78
- () => faker.string.sample({ min: 0, max: 1000 })
79
- ).join(" ")
80
- return sentence
81
- }
10
+ import { highlightJsLanaguages } from "./features/CodeBlock/highlightJsInfo.js"
11
+ import { createGeneratorConfig } from "./utils/generator/createGeneratorConfig.js"
12
+ import { createPsuedoSentence } from "./utils/generator/createPsuedoSentence.js"
13
+ import { createRandomChildCountGenerator } from "./utils/generator/createRandomChildCountGenerator.js"
14
+ import { sometimesZero } from "./utils/generator/sometimesZero.js"
82
15
 
83
16
  export const generatorConfig = [
84
17
  createGeneratorConfig({
85
- isRoot: true,
86
18
  parents: { type: "node", names: ["doc"] },
87
- ignoreValidation: true,
88
- children: { type: "node", names: ["item"] },
89
- create: (_parent, children) => {
19
+ children: {
20
+ type: "node",
21
+ names: [["item", 1]]
22
+ },
23
+ count: createRandomChildCountGenerator({ max: 50, zeroChance: 0 }),
24
+ create: (pm, _parent, children) => {
90
25
  if (!children || children.length === 0) {
91
26
  return pm.doc(pm.list(pm.item({ blockId: nanoid(10) }, pm.paragraph({}, ""))))
92
27
  }
@@ -94,9 +29,12 @@ export const generatorConfig = [
94
29
  }
95
30
  }),
96
31
  createGeneratorConfig({
97
- parents: { type: "node", names: ["list"] },
98
- children: { type: "node", names: ["item"] },
99
- create: (_parent, children) => {
32
+ parents: { type: "node", names: ["list", "doc"] },
33
+ children: { type: "node", names: [
34
+ ["item", 1]
35
+ ] },
36
+ count: createRandomChildCountGenerator({ max: 30 }),
37
+ create: (pm, _parent, children) => {
100
38
  if (!children || children.length === 0) {
101
39
  return pm.list(pm.item({ blockId: nanoid(10) }, pm.paragraph("")))
102
40
  }
@@ -104,18 +42,19 @@ export const generatorConfig = [
104
42
  }
105
43
  }),
106
44
  createGeneratorConfig({
107
- parents: { type: "node", names: ["item"] },
108
- children: { type: "node", names: [
109
- "paragraph",
110
- "heading",
111
- "codeBlock",
112
- "embeddedDoc",
113
- "iframe",
114
- "table",
115
- "image",
116
- "blockquote"
45
+ parents: { type: "node" as const, names: ["item"] },
46
+ children: { type: "node" as const, names: [
47
+ ["paragraph", 14],
48
+ ["heading", 4],
49
+ ["codeBlock", 2],
50
+ ["table", 2],
51
+ ["image", 3],
52
+ ["blockquote", 4],
53
+ ["embeddedDoc", 1],
54
+ ["iframe", 1]
117
55
  ] },
118
- create: (_parent, children) => {
56
+ count: createRandomChildCountGenerator({ max: 20, depthInfluence: 0.5 }),
57
+ create: (pm, _parent, children) => {
119
58
  if (!children || children.length === 0) {
120
59
  return pm.item({ blockId: nanoid(10) }, pm.paragraph(""))
121
60
  }
@@ -135,8 +74,12 @@ export const generatorConfig = [
135
74
  }),
136
75
  createGeneratorConfig({
137
76
  parents: { type: "node", names: ["blockquote"] },
138
- children: { type: "node", names: ["paragraph", "cite"] },
139
- create: (_parent, children) => {
77
+ children: { type: "node", names: [
78
+ ["paragraph", 1],
79
+ ["cite", 1]
80
+ ] },
81
+ count: () => faker.number.int({ min: 1, max: 2 }),
82
+ create: (pm, _parent, children) => {
140
83
  const parTypes = []
141
84
  const citeTypes = []
142
85
  for (const child of children) {
@@ -149,7 +92,7 @@ export const generatorConfig = [
149
92
  if (parTypes.length === 0) {
150
93
  return pm.blockquote({}, pm.paragraph(""))
151
94
  } else {
152
- const someCite = citeTypes.find(_ => _.textContent.length > 0) ?? pm.cite({}, createPsuedoSentence())
95
+ const someCite = citeTypes.find(_ => _.textContent.length > 0) ?? pm.cite({}, createPsuedoSentence({ min: 1 }))
153
96
  return pm.blockquote({}, ...parTypes, someCite)
154
97
  }
155
98
  }
@@ -157,60 +100,62 @@ export const generatorConfig = [
157
100
  createGeneratorConfig({
158
101
  parents: { type: "node", names: ["table"] },
159
102
  children: { type: "node", names: [
160
- "tableHeader",
161
- "tableCell"
103
+ ["tableCell", 1]
162
104
  ] },
163
- ignoreValidation: true, // we're handling the in-between tableRow nodes
164
- create: (_parent, children) => {
165
- const headerType = []
166
- const cellType = []
167
-
168
- for (const child of children) {
169
- if (child.type.name === "tableHeader") {
170
- headerType.push(child)
171
- } else if (child.type.name === "tableCell") {
172
- cellType.push(child)
173
- }
174
- }
175
- const colNum = headerType.length
176
-
177
- if (colNum === 0) {
178
- return pm.table({}, pm.tableRow({}, pm.tableCell(pm.paragraph(""))))
179
- }
180
- const rowCount = Math.ceil(cellType.length / colNum)
105
+ count: createRandomChildCountGenerator({ max: 50, depthInfluence: 0.5, zeroChance: 0 }),
106
+ create: (pm, _parent, children) => {
107
+ const colNum = faker.number.int({ min: 1, max: Math.min(children.length, 10) })
108
+ const rowCount = Math.floor(children.length / colNum)
181
109
  const rows: Node[] = []
110
+ const addHeader = faker.datatype.boolean()
111
+ if (addHeader) {
112
+ const nodes = Array.from(
113
+ { length: colNum },
114
+ () => pm.tableHeader({}, pm.paragraph({}, createPsuedoSentence({ min: 1 })))
115
+ )
116
+ rows.push(pm.tableRow({}, ...nodes))
117
+ }
182
118
  for (let i = 0; i < rowCount; i++) {
183
- rows.push(pm.tableRow({}, ...cellType.slice(i * colNum, (i + 1) * colNum)))
119
+ const rowChildren = children.slice(i * colNum, (i + 1) * colNum)
120
+ if (rowChildren.length === 0) continue
121
+ rows.push(pm.tableRow({}, ...rowChildren))
184
122
  }
185
123
 
186
- return pm.table({}, pm.tableRow({}, ...headerType), ...rows)
124
+ if (rows.length === 0) return undefined
125
+ return pm.table({}, ...rows)
187
126
  }
188
127
  }),
189
128
  createGeneratorConfig({
190
- parents: { type: "node", names: ["tableHeader", "tableCell"] },
191
- children: { type: "node", names: ["paragraph"] },
192
- create: (_parent, children) => {
129
+ parents: { type: "node", names: ["tableCell"] },
130
+ children: { type: "node", names: [
131
+ ["paragraph", 1]
132
+ ] },
133
+ count: () => sometimesZero(1),
134
+ create: (pm, _parent, children) => {
193
135
  if (!children || children.length === 0) {
194
136
  return pm.tableCell(pm.paragraph(""))
195
137
  }
196
138
  return pm.tableCell(...children.slice(0, 1))
197
139
  }
198
140
  }),
141
+
199
142
  createGeneratorConfig({
200
- parents: { type: "node", names: ["paragraph", "heading", "codeBlock", "cite", "heading"] },
143
+ parents: { type: "text", names: ["paragraph", "heading", "codeBlock", "cite", "heading"] },
201
144
  children: { type: "text", names: [
202
- "bold",
203
- "italic",
204
- "underline",
205
- "strike",
206
- "subscript",
207
- "superscript",
208
- "code",
209
- "link"
145
+ ["bold", 1],
146
+ ["italic", 1],
147
+ ["underline", 1],
148
+ ["strike", 1],
149
+ ["subscript", 1],
150
+ ["superscript", 1],
151
+ ["code", 1],
152
+ ["link", 1],
153
+ ["text", 10]
210
154
  ] },
211
- create(parent, children) {
155
+ count: createRandomChildCountGenerator({ max: 5, depthInfluence: 0.2 }),
156
+ create(pm, parent, children) {
212
157
  if (parent === "heading") {
213
- return pm[parent]({ level: 1 }, ...children as any)
158
+ return pm[parent]({ level: faker.number.int({ min: 1, max: 6 }) }, ...children as any)
214
159
  }
215
160
  if (parent === "cite") {
216
161
  // citation must have SOME text
@@ -220,8 +165,18 @@ export const generatorConfig = [
220
165
  const someIndex = faker.number.int({ min: 0, max: children.length })
221
166
  children.splice(someIndex, 0, pm.hardBreak() as any)
222
167
  }
168
+ if (parent === "codeBlock") {
169
+ // aliases contains both the names and the aliases
170
+ const lang = faker.helpers.arrayElement([...Object.keys(highlightJsLanaguages.aliases), undefined])
171
+ const lines = faker.number.int({ min: 1, max: 10 })
172
+ const code = Array.from(
173
+ { length: lines },
174
+ () => createPsuedoSentence()
175
+ ).join("\n")
176
+ return pm[parent]({ language: lang }, code)
177
+ }
223
178
 
224
- return pm[parent]({}, ...children as any)
179
+ return pm[parent]({}, ...children as any) as any
225
180
  }
226
181
  }),
227
182
  createGeneratorConfig({
@@ -235,32 +190,30 @@ export const generatorConfig = [
235
190
  "link"
236
191
  ]
237
192
  },
238
- // note the addition of text
193
+ skipChild(parentType, childType, depth) {
194
+ if (depth > 20) return true
195
+ return parentType === childType
196
+ },
239
197
  children: { type: "text", names: [
240
- "bold",
241
- "italic",
242
- "underline",
243
- "strike",
244
- "subscript",
245
- "superscript",
246
- "link",
247
- "text"
198
+ ["bold", 1],
199
+ ["italic", 1],
200
+ ["underline", 1],
201
+ ["strike", 1],
202
+ ["subscript", 1],
203
+ ["superscript", 1],
204
+ ["link", 1],
205
+ ["text", 10]
248
206
  ] },
249
- ignoreValidation: ["text"] // text is not a real node
250
- // create: (parent, children) => {
251
- // return pm[parent]({}, ...children as any) as any
252
- // }
253
- }),
254
- createGeneratorConfig({
255
- ignoreValidation: true, // text is not a real node
256
- parents: { type: "text", names: ["code"] },
257
- children: { type: "text", names: ["text"] }
207
+ count: createRandomChildCountGenerator({ max: 5, depthInfluence: 0.7 }),
208
+ create: (pm, parent, children) => {
209
+ return pm[parent]({}, ...children as any) as any
210
+ }
258
211
  }),
259
212
  createGeneratorConfig({
260
213
  parents: { type: "text", names: ["text"] },
261
- children: { type: "text" },
262
- create: _parent => {
214
+ create: () => {
263
215
  return createPsuedoSentence()
264
216
  }
265
217
  })
266
218
  ]
219
+
@@ -1,4 +1,4 @@
1
- import { type EditorOptions, type Extension, getSchema, type Mark, type Node } from "@tiptap/core"
1
+ import { type EditorOptions, getSchema } from "@tiptap/core"
2
2
  import { Bold } from "@tiptap/extension-bold"
3
3
  import { Code } from "@tiptap/extension-code"
4
4
  import { Dropcursor } from "@tiptap/extension-dropcursor"
@@ -30,7 +30,7 @@ import { Link } from "./features/Link/Link.js"
30
30
  import { Menus } from "./features/Menus/Menus.js"
31
31
  import { type NodeTableCellName, type NodeTableHeaderName, type NodeTableName, type NodeTableRowName, TableExtensions } from "./features/Tables/index.js"
32
32
 
33
- function stripShortcuts<T extends Node | Mark | Extension>(c: T): T {
33
+ function stripShortcuts<T extends { extend: any }>(c: T): T {
34
34
  return c.extend({
35
35
  addKeyboardShortcuts() {
36
36
  return {}