@prosekit/core 0.8.3 → 0.8.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/editor-KZlceNQ1.d.ts +722 -0
- package/dist/editor-KZlceNQ1.d.ts.map +1 -0
- package/dist/{editor-DlGlYOp-.js → editor-TvRTsFdO.js} +102 -196
- package/dist/editor-TvRTsFdO.js.map +1 -0
- package/dist/prosekit-core-test.d.ts +20 -19
- package/dist/prosekit-core-test.d.ts.map +1 -0
- package/dist/prosekit-core-test.js +5 -8
- package/dist/prosekit-core-test.js.map +1 -0
- package/dist/prosekit-core.d.ts +797 -792
- package/dist/prosekit-core.d.ts.map +1 -0
- package/dist/prosekit-core.js +42 -79
- package/dist/prosekit-core.js.map +1 -0
- package/package.json +14 -12
- package/src/commands/add-mark.ts +53 -0
- package/src/commands/expand-mark.ts +96 -0
- package/src/commands/insert-default-block.spec.ts +102 -0
- package/src/commands/insert-default-block.ts +49 -0
- package/src/commands/insert-node.ts +71 -0
- package/src/commands/insert-text.ts +24 -0
- package/src/commands/remove-mark.ts +54 -0
- package/src/commands/remove-node.ts +43 -0
- package/src/commands/select-all.ts +16 -0
- package/src/commands/set-block-type.ts +64 -0
- package/src/commands/set-node-attrs.ts +68 -0
- package/src/commands/toggle-mark.ts +65 -0
- package/src/commands/toggle-node.ts +47 -0
- package/src/commands/toggle-wrap.spec.ts +35 -0
- package/src/commands/toggle-wrap.ts +42 -0
- package/src/commands/unset-block-type.spec.ts +49 -0
- package/src/commands/unset-block-type.ts +84 -0
- package/src/commands/unset-mark.spec.ts +35 -0
- package/src/commands/unset-mark.ts +38 -0
- package/src/commands/wrap.ts +50 -0
- package/src/editor/action.spec.ts +143 -0
- package/src/editor/action.ts +248 -0
- package/src/editor/editor.spec.ts +186 -0
- package/src/editor/editor.ts +563 -0
- package/src/editor/union.spec.ts +108 -0
- package/src/editor/union.ts +47 -0
- package/src/editor/with-priority.ts +25 -0
- package/src/error.ts +28 -0
- package/src/extensions/clipboard-serializer.ts +107 -0
- package/src/extensions/command.ts +121 -0
- package/src/extensions/default-state.spec.ts +60 -0
- package/src/extensions/default-state.ts +76 -0
- package/src/extensions/doc.ts +31 -0
- package/src/extensions/events/doc-change.ts +34 -0
- package/src/extensions/events/dom-event.spec.ts +70 -0
- package/src/extensions/events/dom-event.ts +117 -0
- package/src/extensions/events/editor-event.ts +293 -0
- package/src/extensions/events/focus.spec.ts +50 -0
- package/src/extensions/events/focus.ts +28 -0
- package/src/extensions/events/plugin-view.ts +132 -0
- package/src/extensions/history.ts +81 -0
- package/src/extensions/keymap-base.ts +60 -0
- package/src/extensions/keymap.spec.ts +125 -0
- package/src/extensions/keymap.ts +96 -0
- package/src/extensions/mark-spec.spec.ts +177 -0
- package/src/extensions/mark-spec.ts +181 -0
- package/src/extensions/mark-view-effect.ts +85 -0
- package/src/extensions/mark-view.ts +43 -0
- package/src/extensions/node-spec.spec.ts +224 -0
- package/src/extensions/node-spec.ts +199 -0
- package/src/extensions/node-view-effect.ts +85 -0
- package/src/extensions/node-view.ts +43 -0
- package/src/extensions/paragraph.ts +61 -0
- package/src/extensions/plugin.spec.ts +153 -0
- package/src/extensions/plugin.ts +81 -0
- package/src/extensions/text.ts +34 -0
- package/src/facets/base-extension.ts +54 -0
- package/src/facets/command.ts +21 -0
- package/src/facets/facet-extension.spec.ts +173 -0
- package/src/facets/facet-extension.ts +53 -0
- package/src/facets/facet-node.spec.ts +265 -0
- package/src/facets/facet-node.ts +185 -0
- package/src/facets/facet-types.ts +9 -0
- package/src/facets/facet.spec.ts +76 -0
- package/src/facets/facet.ts +84 -0
- package/src/facets/root.ts +44 -0
- package/src/facets/schema-spec.ts +30 -0
- package/src/facets/schema.ts +26 -0
- package/src/facets/state.spec.ts +53 -0
- package/src/facets/state.ts +85 -0
- package/src/facets/union-extension.ts +41 -0
- package/src/index.ts +302 -0
- package/src/test/index.ts +4 -0
- package/src/test/test-builder.ts +68 -0
- package/src/test/test-editor.spec.ts +104 -0
- package/src/test/test-editor.ts +113 -0
- package/src/testing/index.ts +283 -0
- package/src/testing/keyboard.ts +5 -0
- package/src/types/any-function.ts +4 -0
- package/src/types/assert-type-equal.ts +8 -0
- package/src/types/attrs.ts +32 -0
- package/src/types/base-node-view-options.ts +33 -0
- package/src/types/dom-node.ts +1 -0
- package/src/types/extension-command.ts +52 -0
- package/src/types/extension-mark.ts +15 -0
- package/src/types/extension-node.ts +15 -0
- package/src/types/extension.spec.ts +56 -0
- package/src/types/extension.ts +168 -0
- package/src/types/model.ts +54 -0
- package/src/types/object-entries.ts +13 -0
- package/src/types/pick-string-literal.spec.ts +10 -0
- package/src/types/pick-string-literal.ts +6 -0
- package/src/types/pick-sub-type.spec.ts +20 -0
- package/src/types/pick-sub-type.ts +6 -0
- package/src/types/priority.ts +12 -0
- package/src/types/setter.ts +4 -0
- package/src/types/simplify-deeper.spec.ts +40 -0
- package/src/types/simplify-deeper.ts +6 -0
- package/src/types/simplify-union.spec.ts +21 -0
- package/src/types/simplify-union.ts +11 -0
- package/src/utils/array-grouping.spec.ts +29 -0
- package/src/utils/array-grouping.ts +25 -0
- package/src/utils/array.ts +21 -0
- package/src/utils/assert.ts +13 -0
- package/src/utils/attrs-match.ts +20 -0
- package/src/utils/can-use-regex-lookbehind.ts +12 -0
- package/src/utils/clsx.spec.ts +14 -0
- package/src/utils/clsx.ts +14 -0
- package/src/utils/collect-children.ts +21 -0
- package/src/utils/collect-nodes.ts +37 -0
- package/src/utils/combine-event-handlers.spec.ts +27 -0
- package/src/utils/combine-event-handlers.ts +27 -0
- package/src/utils/contains-inline-node.ts +17 -0
- package/src/utils/deep-equals.spec.ts +26 -0
- package/src/utils/deep-equals.ts +29 -0
- package/src/utils/default-block-at.ts +15 -0
- package/src/utils/editor-content.spec.ts +47 -0
- package/src/utils/editor-content.ts +77 -0
- package/src/utils/env.ts +6 -0
- package/src/utils/find-parent-node-of-type.ts +29 -0
- package/src/utils/find-parent-node.spec.ts +68 -0
- package/src/utils/find-parent-node.ts +55 -0
- package/src/utils/get-custom-selection.ts +19 -0
- package/src/utils/get-dom-api.ts +56 -0
- package/src/utils/get-id.spec.ts +14 -0
- package/src/utils/get-id.ts +13 -0
- package/src/utils/get-mark-type.ts +20 -0
- package/src/utils/get-node-type.ts +20 -0
- package/src/utils/get-node-types.ts +19 -0
- package/src/utils/includes-mark.ts +18 -0
- package/src/utils/is-at-block-start.ts +26 -0
- package/src/utils/is-in-code-block.ts +18 -0
- package/src/utils/is-mark-absent.spec.ts +53 -0
- package/src/utils/is-mark-absent.ts +42 -0
- package/src/utils/is-mark-active.ts +27 -0
- package/src/utils/is-node-active.ts +25 -0
- package/src/utils/is-subset.spec.ts +12 -0
- package/src/utils/is-subset.ts +11 -0
- package/src/utils/maybe-run.spec.ts +39 -0
- package/src/utils/maybe-run.ts +11 -0
- package/src/utils/merge-objects.spec.ts +30 -0
- package/src/utils/merge-objects.ts +11 -0
- package/src/utils/merge-specs.ts +35 -0
- package/src/utils/object-equal.spec.ts +26 -0
- package/src/utils/object-equal.ts +28 -0
- package/src/utils/output-spec.test.ts +95 -0
- package/src/utils/output-spec.ts +130 -0
- package/src/utils/parse.spec.ts +46 -0
- package/src/utils/parse.ts +321 -0
- package/src/utils/remove-undefined-values.spec.ts +15 -0
- package/src/utils/remove-undefined-values.ts +9 -0
- package/src/utils/set-selection-around.ts +11 -0
- package/src/utils/type-assertion.ts +91 -0
- package/src/utils/unicode.spec.ts +10 -0
- package/src/utils/unicode.ts +4 -0
- package/src/utils/with-skip-code-block.ts +15 -0
- package/dist/editor-OUH5V8BA.d.ts +0 -754
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import type { ProseMirrorNode } from '@prosekit/pm/model'
|
|
2
|
+
import {
|
|
3
|
+
NodeSelection,
|
|
4
|
+
TextSelection,
|
|
5
|
+
type Selection,
|
|
6
|
+
} from '@prosekit/pm/state'
|
|
7
|
+
|
|
8
|
+
import {
|
|
9
|
+
createMarkActions,
|
|
10
|
+
createNodeActions,
|
|
11
|
+
} from '../editor/action'
|
|
12
|
+
import {
|
|
13
|
+
Editor,
|
|
14
|
+
EditorInstance,
|
|
15
|
+
setupEditorExtension,
|
|
16
|
+
type EditorOptions,
|
|
17
|
+
} from '../editor/editor'
|
|
18
|
+
import type { Extension } from '../types/extension'
|
|
19
|
+
import type {
|
|
20
|
+
NodeJSON,
|
|
21
|
+
SelectionJSON,
|
|
22
|
+
} from '../types/model'
|
|
23
|
+
import { isProseMirrorNode } from '../utils/type-assertion'
|
|
24
|
+
|
|
25
|
+
import {
|
|
26
|
+
applyMarkForTest,
|
|
27
|
+
createNodeForTest,
|
|
28
|
+
type TaggedProseMirrorNode,
|
|
29
|
+
} from './test-builder'
|
|
30
|
+
|
|
31
|
+
function maybeResolve(doc: ProseMirrorNode, pos?: number) {
|
|
32
|
+
if (pos != null) {
|
|
33
|
+
return doc.resolve(pos)
|
|
34
|
+
}
|
|
35
|
+
return undefined
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function getSelection(doc: TaggedProseMirrorNode): Selection {
|
|
39
|
+
const tags = doc.tags
|
|
40
|
+
const $a = maybeResolve(doc, tags?.a)
|
|
41
|
+
const $b = maybeResolve(doc, tags?.b)
|
|
42
|
+
|
|
43
|
+
if ($a) {
|
|
44
|
+
if ($a.parent.inlineContent) {
|
|
45
|
+
return new TextSelection($a, $b)
|
|
46
|
+
} else {
|
|
47
|
+
return new NodeSelection($a)
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return TextSelection.atStart(doc)
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
class TestEditorInstance extends EditorInstance {
|
|
54
|
+
constructor(extension: Extension) {
|
|
55
|
+
super(extension)
|
|
56
|
+
this.nodes = createNodeActions(this.schema, this.getState, createNodeForTest)
|
|
57
|
+
this.marks = createMarkActions(this.schema, this.getState, applyMarkForTest)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
override setContent(
|
|
61
|
+
content: ProseMirrorNode | NodeJSON | string | HTMLElement,
|
|
62
|
+
selection?: SelectionJSON | Selection | 'start' | 'end',
|
|
63
|
+
): void {
|
|
64
|
+
return super.setContent(
|
|
65
|
+
content,
|
|
66
|
+
isProseMirrorNode(content) && !selection
|
|
67
|
+
? getSelection(content)
|
|
68
|
+
: selection,
|
|
69
|
+
)
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* An editor for testing purposes.
|
|
75
|
+
* @public
|
|
76
|
+
*/
|
|
77
|
+
export class TestEditor<E extends Extension = Extension> extends Editor<E> {
|
|
78
|
+
constructor(instance: EditorInstance) {
|
|
79
|
+
super(instance)
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Set the editor state to the given document. You can use special tokens
|
|
84
|
+
* `<a>` and `<b>` to set the anchor and head positions of the selection.
|
|
85
|
+
*
|
|
86
|
+
* @example
|
|
87
|
+
*
|
|
88
|
+
* ```ts
|
|
89
|
+
* const editor = createTestEditor({ extension })
|
|
90
|
+
* const n = editor.nodes
|
|
91
|
+
* const doc = n.doc(n.paragraph('<a>Hello<b> world!'))
|
|
92
|
+
* editor.set(doc) // "Hello" is selected.
|
|
93
|
+
* ```
|
|
94
|
+
*/
|
|
95
|
+
set(doc: ProseMirrorNode): void {
|
|
96
|
+
return this.setContent(doc)
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
dispatchEvent(event: Event): void {
|
|
100
|
+
this.view.dispatchEvent(event)
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* @public
|
|
106
|
+
*/
|
|
107
|
+
export function createTestEditor<E extends Extension>(
|
|
108
|
+
options: EditorOptions<E>,
|
|
109
|
+
): TestEditor<E> {
|
|
110
|
+
const extension = setupEditorExtension(options)
|
|
111
|
+
const instance = new TestEditorInstance(extension)
|
|
112
|
+
return new TestEditor(instance)
|
|
113
|
+
}
|
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
import '@prosekit/pm/view/style/prosemirror.css'
|
|
2
|
+
|
|
3
|
+
import type { Attrs } from '@prosekit/pm/model'
|
|
4
|
+
|
|
5
|
+
import { union } from '../editor/union'
|
|
6
|
+
import { withPriority } from '../editor/with-priority'
|
|
7
|
+
import { defineBaseCommands } from '../extensions/command'
|
|
8
|
+
import { defineHistory } from '../extensions/history'
|
|
9
|
+
import { defineBaseKeymap } from '../extensions/keymap-base'
|
|
10
|
+
import { defineMarkSpec } from '../extensions/mark-spec'
|
|
11
|
+
import { defineNodeSpec } from '../extensions/node-spec'
|
|
12
|
+
import {
|
|
13
|
+
createTestEditor,
|
|
14
|
+
type TestEditor,
|
|
15
|
+
} from '../test'
|
|
16
|
+
import type {
|
|
17
|
+
Extension,
|
|
18
|
+
ExtractMarkActions,
|
|
19
|
+
ExtractNodeActions,
|
|
20
|
+
} from '../types/extension'
|
|
21
|
+
import { Priority } from '../types/priority'
|
|
22
|
+
|
|
23
|
+
type DocExtension = Extension<{ Nodes: { doc: Attrs } }>
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* @internal
|
|
27
|
+
*/
|
|
28
|
+
export function defineDoc(): DocExtension {
|
|
29
|
+
return defineNodeSpec({
|
|
30
|
+
name: 'doc',
|
|
31
|
+
content: 'block+',
|
|
32
|
+
topNode: true,
|
|
33
|
+
})
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
type ParagraphExtension = Extension<{
|
|
37
|
+
Nodes: {
|
|
38
|
+
paragraph: Attrs
|
|
39
|
+
}
|
|
40
|
+
}>
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* @internal
|
|
44
|
+
*/
|
|
45
|
+
function defineParagraphSpec(): ParagraphExtension {
|
|
46
|
+
return defineNodeSpec({
|
|
47
|
+
name: 'paragraph',
|
|
48
|
+
content: 'inline*',
|
|
49
|
+
group: 'block',
|
|
50
|
+
parseDOM: [{ tag: 'p' }],
|
|
51
|
+
toDOM() {
|
|
52
|
+
return ['p', 0]
|
|
53
|
+
},
|
|
54
|
+
})
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* @internal
|
|
59
|
+
*/
|
|
60
|
+
export function defineParagraph(): ParagraphExtension {
|
|
61
|
+
return withPriority(defineParagraphSpec(), Priority.highest)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
type TextExtension = Extension<{
|
|
65
|
+
Nodes: {
|
|
66
|
+
text: Attrs
|
|
67
|
+
}
|
|
68
|
+
}>
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* @internal
|
|
72
|
+
*/
|
|
73
|
+
export function defineText(): TextExtension {
|
|
74
|
+
return defineNodeSpec({
|
|
75
|
+
name: 'text',
|
|
76
|
+
group: 'inline',
|
|
77
|
+
})
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
type BoldExtension = Extension<{
|
|
81
|
+
Marks: {
|
|
82
|
+
bold: Attrs
|
|
83
|
+
}
|
|
84
|
+
}>
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* @internal
|
|
88
|
+
*/
|
|
89
|
+
function defineBold(): BoldExtension {
|
|
90
|
+
return defineMarkSpec({
|
|
91
|
+
name: 'bold',
|
|
92
|
+
parseDOM: [{ tag: 'strong' }],
|
|
93
|
+
toDOM() {
|
|
94
|
+
return ['strong', 0]
|
|
95
|
+
},
|
|
96
|
+
})
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
type ItalicExtension = Extension<{
|
|
100
|
+
Marks: {
|
|
101
|
+
italic: Attrs
|
|
102
|
+
}
|
|
103
|
+
}>
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* @internal
|
|
107
|
+
*/
|
|
108
|
+
function defineItalic(): ItalicExtension {
|
|
109
|
+
return defineMarkSpec({
|
|
110
|
+
name: 'italic',
|
|
111
|
+
parseDOM: [{ tag: 'em' }],
|
|
112
|
+
toDOM() {
|
|
113
|
+
return ['em', 0]
|
|
114
|
+
},
|
|
115
|
+
})
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
interface LinkAttrs {
|
|
119
|
+
href: string
|
|
120
|
+
target?: string | null
|
|
121
|
+
rel?: string | null
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
type LinkExtension = Extension<{
|
|
125
|
+
Marks: {
|
|
126
|
+
link: LinkAttrs
|
|
127
|
+
}
|
|
128
|
+
}>
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* @internal
|
|
132
|
+
*/
|
|
133
|
+
function defineLink(): LinkExtension {
|
|
134
|
+
return defineMarkSpec<'link', LinkAttrs>({
|
|
135
|
+
name: 'link',
|
|
136
|
+
inclusive: false,
|
|
137
|
+
attrs: {
|
|
138
|
+
href: { validate: 'string' },
|
|
139
|
+
target: { default: null, validate: 'string|null' },
|
|
140
|
+
rel: { default: null, validate: 'string|null' },
|
|
141
|
+
},
|
|
142
|
+
parseDOM: [
|
|
143
|
+
{
|
|
144
|
+
tag: 'a[href]',
|
|
145
|
+
getAttrs: (dom: HTMLElement) => {
|
|
146
|
+
return {
|
|
147
|
+
href: dom.getAttribute('href') || '',
|
|
148
|
+
target: dom.getAttribute('target') || null,
|
|
149
|
+
rel: dom.getAttribute('rel') || null,
|
|
150
|
+
}
|
|
151
|
+
},
|
|
152
|
+
},
|
|
153
|
+
],
|
|
154
|
+
toDOM(node) {
|
|
155
|
+
const { href, target, rel } = node.attrs as LinkAttrs
|
|
156
|
+
return ['a', { href, target, rel }, 0]
|
|
157
|
+
},
|
|
158
|
+
})
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
type HeadingExtension = Extension<{
|
|
162
|
+
Nodes: {
|
|
163
|
+
heading: Attrs
|
|
164
|
+
}
|
|
165
|
+
}>
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* @internal
|
|
169
|
+
*/
|
|
170
|
+
function defineHeading(): HeadingExtension {
|
|
171
|
+
return defineNodeSpec({
|
|
172
|
+
name: 'heading',
|
|
173
|
+
content: 'inline*',
|
|
174
|
+
group: 'block',
|
|
175
|
+
defining: true,
|
|
176
|
+
parseDOM: [{ tag: 'h1' }],
|
|
177
|
+
toDOM() {
|
|
178
|
+
return ['h1', 0]
|
|
179
|
+
},
|
|
180
|
+
})
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
type CodeBlockExtension = Extension<{
|
|
184
|
+
Nodes: {
|
|
185
|
+
codeBlock: { language: string }
|
|
186
|
+
}
|
|
187
|
+
}>
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* @internal
|
|
191
|
+
*/
|
|
192
|
+
function defineCodeBlock(): CodeBlockExtension {
|
|
193
|
+
return defineNodeSpec({
|
|
194
|
+
name: 'codeBlock',
|
|
195
|
+
content: 'text*',
|
|
196
|
+
group: 'block',
|
|
197
|
+
code: true,
|
|
198
|
+
defining: true,
|
|
199
|
+
marks: '',
|
|
200
|
+
attrs: { language: { default: '', validate: 'string' } },
|
|
201
|
+
toDOM() {
|
|
202
|
+
return ['pre', ['code', 0]]
|
|
203
|
+
},
|
|
204
|
+
})
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
type BlockquoteExtension = Extension<{
|
|
208
|
+
Nodes: {
|
|
209
|
+
blockquote: Attrs
|
|
210
|
+
}
|
|
211
|
+
}>
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* @internal
|
|
215
|
+
*/
|
|
216
|
+
function defineBlockquote(): BlockquoteExtension {
|
|
217
|
+
return defineNodeSpec({
|
|
218
|
+
name: 'blockquote',
|
|
219
|
+
content: 'block+',
|
|
220
|
+
group: 'block',
|
|
221
|
+
defining: true,
|
|
222
|
+
parseDOM: [{ tag: 'blockquote' }],
|
|
223
|
+
toDOM() {
|
|
224
|
+
return ['blockquote', 0]
|
|
225
|
+
},
|
|
226
|
+
})
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* @internal
|
|
231
|
+
*/
|
|
232
|
+
export function defineTestExtension() {
|
|
233
|
+
return union(
|
|
234
|
+
defineBaseCommands(),
|
|
235
|
+
defineBaseKeymap(),
|
|
236
|
+
defineDoc(),
|
|
237
|
+
defineHistory(),
|
|
238
|
+
defineParagraph(),
|
|
239
|
+
defineText(),
|
|
240
|
+
defineBold(),
|
|
241
|
+
defineItalic(),
|
|
242
|
+
defineLink(),
|
|
243
|
+
defineHeading(),
|
|
244
|
+
defineCodeBlock(),
|
|
245
|
+
defineBlockquote(),
|
|
246
|
+
)
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* @internal
|
|
251
|
+
*/
|
|
252
|
+
export function setupTestFromExtension<E extends Extension>(
|
|
253
|
+
extension: E,
|
|
254
|
+
): {
|
|
255
|
+
editor: TestEditor<E>
|
|
256
|
+
n: ExtractNodeActions<E>
|
|
257
|
+
m: ExtractMarkActions<E>
|
|
258
|
+
} {
|
|
259
|
+
const editor = createTestEditor({ extension })
|
|
260
|
+
|
|
261
|
+
const div = document.body.appendChild(document.createElement('div'))
|
|
262
|
+
div.style.minWidth = '200px'
|
|
263
|
+
div.style.minHeight = '200px'
|
|
264
|
+
editor.mount(div)
|
|
265
|
+
editor.view.dom.focus()
|
|
266
|
+
|
|
267
|
+
const n = editor.nodes
|
|
268
|
+
const m = editor.marks
|
|
269
|
+
return { editor, n, m }
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* @internal
|
|
274
|
+
*/
|
|
275
|
+
export function setupTest() {
|
|
276
|
+
const { editor, m, n } = setupTestFromExtension(defineTestExtension())
|
|
277
|
+
|
|
278
|
+
return {
|
|
279
|
+
editor,
|
|
280
|
+
m,
|
|
281
|
+
n: { ...n, p: n.paragraph },
|
|
282
|
+
}
|
|
283
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { Attrs } from '@prosekit/pm/model'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* An object holding the attributes of a node.
|
|
5
|
+
|
|
6
|
+
* @public
|
|
7
|
+
*/
|
|
8
|
+
export type AnyAttrs = Attrs
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @public
|
|
12
|
+
*/
|
|
13
|
+
export type AttrSpec<AttrType = any> = {
|
|
14
|
+
/**
|
|
15
|
+
* The default value for this attribute, to use when no explicit value is
|
|
16
|
+
* provided. Attributes that have no default must be provided whenever a node
|
|
17
|
+
* or mark of a type that has them is created.
|
|
18
|
+
*/
|
|
19
|
+
default?: AttrType
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* A function or type name used to validate values of this attribute. This
|
|
23
|
+
* will be used when deserializing the attribute from JSON, and when running
|
|
24
|
+
* [`Node.check`](https://prosemirror.net/docs/ref/#model.Node.check). When a
|
|
25
|
+
* function, it should raise an exception if the value isn't of the expected
|
|
26
|
+
* type or shape. When a string, it should be a `|`-separated string of
|
|
27
|
+
* primitive types (`"number"`, `"string"`, `"boolean"`, `"null"`, and
|
|
28
|
+
* `"undefined"`), and the library will raise an error when the value is not
|
|
29
|
+
* one of those types.
|
|
30
|
+
*/
|
|
31
|
+
validate?: string | ((value: unknown) => void)
|
|
32
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { ProseMirrorNode } from '@prosekit/pm/model'
|
|
2
|
+
import type { NodeView } from '@prosekit/pm/view'
|
|
3
|
+
|
|
4
|
+
// This should be synced with the type `CoreNodeViewUserOptions` from `@prosemirror-adapter/core`
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Some basic props for custom node views.
|
|
8
|
+
*
|
|
9
|
+
* @deprecated - This is no longer needed. Use `CoreNodeViewUserOptions` from `@prosemirror-adapter/core` instead.
|
|
10
|
+
*
|
|
11
|
+
* @hidden
|
|
12
|
+
*/
|
|
13
|
+
export interface BaseNodeViewOptions {
|
|
14
|
+
/**
|
|
15
|
+
* The wrapping DOM element for the node view. Defaults to `div` for block nodes and `span` for inline nodes.
|
|
16
|
+
*/
|
|
17
|
+
as?: string | HTMLElement | ((node: ProseMirrorNode) => HTMLElement)
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* The wrapping DOM element for the node view's content. Defaults to `div` for block nodes and `span` for inline nodes.
|
|
21
|
+
*/
|
|
22
|
+
contentAs?: string | HTMLElement | ((node: ProseMirrorNode) => HTMLElement)
|
|
23
|
+
|
|
24
|
+
update?: NodeView['update']
|
|
25
|
+
ignoreMutation?: NodeView['ignoreMutation']
|
|
26
|
+
selectNode?: NodeView['selectNode']
|
|
27
|
+
deselectNode?: NodeView['deselectNode']
|
|
28
|
+
setSelection?: NodeView['setSelection']
|
|
29
|
+
stopEvent?: NodeView['stopEvent']
|
|
30
|
+
destroy?: NodeView['destroy']
|
|
31
|
+
|
|
32
|
+
onUpdate?: () => void
|
|
33
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type DOMNode = InstanceType<typeof window.Node>
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { Command } from '@prosekit/pm/state'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* A function to apply a command to the editor. It will return `true` if the command was applied, and `false` otherwise.
|
|
5
|
+
*
|
|
6
|
+
* It also has a `canExec` method to check if the command can be applied.
|
|
7
|
+
*
|
|
8
|
+
* @public
|
|
9
|
+
*/
|
|
10
|
+
export interface CommandAction<Args extends any[] = any[]> {
|
|
11
|
+
/**
|
|
12
|
+
* Execute the current command. Return `true` if the command was successfully
|
|
13
|
+
* executed, otherwise `false`.
|
|
14
|
+
*/
|
|
15
|
+
(...args: Args): boolean
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Check if the current command can be executed. Return `true` if the command
|
|
19
|
+
* can be executed, otherwise `false`.
|
|
20
|
+
*/
|
|
21
|
+
canExec(...args: Args): boolean
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* An alias for `canExec`.
|
|
25
|
+
*
|
|
26
|
+
* @deprecated Use `canExec` instead.
|
|
27
|
+
*/
|
|
28
|
+
canApply(...args: Args): boolean
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export type CommandCreator<Args extends any[] = any[]> = (
|
|
32
|
+
...arg: Args
|
|
33
|
+
) => Command
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* @internal
|
|
37
|
+
*/
|
|
38
|
+
export interface CommandTyping {
|
|
39
|
+
[name: string]: any[]
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface CommandCreators {
|
|
43
|
+
[name: string]: CommandCreator
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export type ToCommandCreators<T extends CommandTyping> = {
|
|
47
|
+
[K in keyof T]: CommandCreator<T[K]>
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export type ToCommandAction<T extends CommandTyping> = {
|
|
51
|
+
[K in keyof T]: CommandAction<T[K]>
|
|
52
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { MarkAction } from '../editor/action'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @internal
|
|
5
|
+
*/
|
|
6
|
+
export interface MarkTyping {
|
|
7
|
+
[name: string]: Record<string, any>
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @internal
|
|
12
|
+
*/
|
|
13
|
+
export type ToMarkAction<T extends MarkTyping> = {
|
|
14
|
+
[K in keyof T]: MarkAction<T[K]>
|
|
15
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { NodeAction } from '../editor/action'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @internal
|
|
5
|
+
*/
|
|
6
|
+
export interface NodeTyping {
|
|
7
|
+
[name: string]: Record<string, any>
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @internal
|
|
12
|
+
*/
|
|
13
|
+
export type ToNodeAction<T extends NodeTyping> = {
|
|
14
|
+
[K in keyof T]: NodeAction<T[K]>
|
|
15
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { test } from 'vitest'
|
|
2
|
+
|
|
3
|
+
import { assertTypeEqual } from './assert-type-equal'
|
|
4
|
+
import type {
|
|
5
|
+
Extension,
|
|
6
|
+
Union,
|
|
7
|
+
} from './extension'
|
|
8
|
+
|
|
9
|
+
test('ExtractTyping', () => {
|
|
10
|
+
type E1 = Extension<{
|
|
11
|
+
Nodes: { foo: { attr1: string } }
|
|
12
|
+
}>
|
|
13
|
+
type E2 = Extension<{
|
|
14
|
+
Nodes: { foo: { attr2: number } }
|
|
15
|
+
}>
|
|
16
|
+
type E3 = Extension<{
|
|
17
|
+
Marks: { bar: { attr3: boolean } }
|
|
18
|
+
}>
|
|
19
|
+
type E4 = Extension<{
|
|
20
|
+
Commands: { a: [''] }
|
|
21
|
+
}>
|
|
22
|
+
type E5 = Extension<{
|
|
23
|
+
Nodes: { baz: { attr4: null } }
|
|
24
|
+
|
|
25
|
+
Commands: { b: [string, number]; c: [{ c: boolean }] }
|
|
26
|
+
}>
|
|
27
|
+
type E6 = Extension<{
|
|
28
|
+
Nodes: never
|
|
29
|
+
Marks: never
|
|
30
|
+
Commands: never
|
|
31
|
+
}>
|
|
32
|
+
type E7 = Extension<{
|
|
33
|
+
Nodes: any
|
|
34
|
+
Marks: any
|
|
35
|
+
Commands: any
|
|
36
|
+
}>
|
|
37
|
+
type E = [E1, E2, E3, E4, E5, E6, E7]
|
|
38
|
+
|
|
39
|
+
type Received = Union<E>
|
|
40
|
+
type Expected = Extension<{
|
|
41
|
+
Nodes: {
|
|
42
|
+
foo: { attr1: string; attr2: number }
|
|
43
|
+
baz: { attr4: null }
|
|
44
|
+
}
|
|
45
|
+
Marks: {
|
|
46
|
+
bar: { attr3: boolean }
|
|
47
|
+
}
|
|
48
|
+
Commands: {
|
|
49
|
+
a: ['']
|
|
50
|
+
b: [string, number]
|
|
51
|
+
c: [{ c: boolean }]
|
|
52
|
+
}
|
|
53
|
+
}>
|
|
54
|
+
|
|
55
|
+
assertTypeEqual<Received, Expected>(true)
|
|
56
|
+
})
|