@prosekit/core 0.8.3 → 0.8.4
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-CfkZ4TNU.d.ts +748 -0
- package/dist/editor-CfkZ4TNU.d.ts.map +1 -0
- package/dist/{editor-DlGlYOp-.js → editor-CizSwUN8.js} +76 -168
- package/dist/editor-CizSwUN8.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 +4 -5
- package/dist/prosekit-core-test.js.map +1 -0
- package/dist/prosekit-core.d.ts +766 -743
- package/dist/prosekit-core.d.ts.map +1 -0
- package/dist/prosekit-core.js +26 -43
- package/dist/prosekit-core.js.map +1 -0
- package/package.json +12 -9
- 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 +89 -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.ts +91 -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.ts +57 -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 +12 -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,248 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
Attrs,
|
|
3
|
+
Mark,
|
|
4
|
+
MarkType,
|
|
5
|
+
NodeType,
|
|
6
|
+
ProseMirrorNode,
|
|
7
|
+
Schema,
|
|
8
|
+
} from '@prosekit/pm/model'
|
|
9
|
+
import type { EditorState } from '@prosekit/pm/state'
|
|
10
|
+
import mapValues from 'just-map-values'
|
|
11
|
+
|
|
12
|
+
import { ProseKitError } from '../error'
|
|
13
|
+
import type { AnyAttrs } from '../types/attrs'
|
|
14
|
+
import { assert } from '../utils/assert'
|
|
15
|
+
import { isMarkActive } from '../utils/is-mark-active'
|
|
16
|
+
import { isNodeActive } from '../utils/is-node-active'
|
|
17
|
+
import { isProseMirrorNode } from '../utils/type-assertion'
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Available children parameters for {@link NodeAction} and {@link MarkAction}.
|
|
21
|
+
*
|
|
22
|
+
* @public
|
|
23
|
+
*/
|
|
24
|
+
export type NodeChild = ProseMirrorNode | string | NodeChild[]
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* A function for creating a node with optional attributes and any number of
|
|
28
|
+
* children.
|
|
29
|
+
*
|
|
30
|
+
* It also has a `isActive` method for checking if the node is active in the
|
|
31
|
+
* current editor selection.
|
|
32
|
+
*
|
|
33
|
+
* @public
|
|
34
|
+
*/
|
|
35
|
+
export interface NodeAction<Attrs extends AnyAttrs = AnyAttrs> {
|
|
36
|
+
/**
|
|
37
|
+
* Creates a node with attributes and any number of children.
|
|
38
|
+
*/
|
|
39
|
+
(attrs: Attrs | null, ...children: NodeChild[]): ProseMirrorNode
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Creates a node with any number of children.
|
|
43
|
+
*/
|
|
44
|
+
(...children: NodeChild[]): ProseMirrorNode
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Checks if the node is active in the current editor selection. If the
|
|
48
|
+
* optional `attrs` parameter is provided, it will check if the node is active
|
|
49
|
+
* with the given attributes.
|
|
50
|
+
*/
|
|
51
|
+
isActive: (attrs?: Attrs) => boolean
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* A function for applying a mark with optional attributes and any number of
|
|
56
|
+
* children.
|
|
57
|
+
*
|
|
58
|
+
* It also has a `isActive` method for checking if the mark is active in the
|
|
59
|
+
* current editor selection.
|
|
60
|
+
*
|
|
61
|
+
* @public
|
|
62
|
+
*/
|
|
63
|
+
export interface MarkAction<Attrs extends AnyAttrs = AnyAttrs> {
|
|
64
|
+
/**
|
|
65
|
+
* Applies a mark with attributes and any number of children.
|
|
66
|
+
*/
|
|
67
|
+
(attrs: Attrs | null, ...children: NodeChild[]): ProseMirrorNode[]
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Applies a mark with any number of children.
|
|
71
|
+
*/
|
|
72
|
+
(...children: NodeChild[]): ProseMirrorNode[]
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Checks if the mark is active in the current editor selection. If the
|
|
76
|
+
* optional `attrs` parameter is provided, it will check if the mark is active
|
|
77
|
+
* with the given attributes.
|
|
78
|
+
*/
|
|
79
|
+
isActive: (attrs?: Attrs) => boolean
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* @deprecated Use type {@link NodeAction} instead.
|
|
84
|
+
*/
|
|
85
|
+
export type NodeBuilder = NodeAction
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* @deprecated Use type {@link MarkAction} instead.
|
|
89
|
+
*/
|
|
90
|
+
export type MarkBuilder = MarkAction
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* @internal
|
|
94
|
+
*/
|
|
95
|
+
export function createNodeActions(
|
|
96
|
+
schema: Schema,
|
|
97
|
+
getState: GetStateFunction,
|
|
98
|
+
createNode: CreateNodeFunction = defaultCreateNode,
|
|
99
|
+
): Record<string, NodeAction> {
|
|
100
|
+
return mapValues(schema.nodes, (type) => createNodeAction(type, getState, createNode))
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function createNodeAction(
|
|
104
|
+
type: NodeType,
|
|
105
|
+
getState: GetStateFunction,
|
|
106
|
+
createNode: CreateNodeFunction,
|
|
107
|
+
): NodeAction {
|
|
108
|
+
const action = (
|
|
109
|
+
...args: [Attrs | NodeChild | null | undefined, ...NodeChild[]]
|
|
110
|
+
) => buildNode(type, args, createNode)
|
|
111
|
+
action.isActive = (attrs?: Attrs) => {
|
|
112
|
+
const state = getState()
|
|
113
|
+
return state ? isNodeActive(state, type, attrs) : false
|
|
114
|
+
}
|
|
115
|
+
return action
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* @internal
|
|
120
|
+
*/
|
|
121
|
+
export function createMarkActions(
|
|
122
|
+
schema: Schema,
|
|
123
|
+
getState: GetStateFunction,
|
|
124
|
+
applyMark: ApplyMarkFunction = defaultApplyMark,
|
|
125
|
+
): Record<string, MarkAction> {
|
|
126
|
+
return mapValues(schema.marks, (type) => createMarkAction(type, getState, applyMark))
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
function createMarkAction(
|
|
130
|
+
type: MarkType,
|
|
131
|
+
getState: GetStateFunction,
|
|
132
|
+
applyMark: ApplyMarkFunction,
|
|
133
|
+
): MarkAction {
|
|
134
|
+
const action = (
|
|
135
|
+
...args: [Attrs | NodeChild | null | undefined, ...NodeChild[]]
|
|
136
|
+
) => buildMark(type, args, applyMark)
|
|
137
|
+
action.isActive = (attrs?: Attrs) => {
|
|
138
|
+
const state = getState()
|
|
139
|
+
return state ? isMarkActive(state, type, attrs) : false
|
|
140
|
+
}
|
|
141
|
+
return action
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
function buildMark(
|
|
145
|
+
type: MarkType,
|
|
146
|
+
args: [Attrs | NodeChild | null | undefined, ...NodeChild[]],
|
|
147
|
+
applyMark: ApplyMarkFunction,
|
|
148
|
+
): ProseMirrorNode[] {
|
|
149
|
+
const [attrs, children] = normalizeArgs(args)
|
|
150
|
+
const mark = type.create(attrs)
|
|
151
|
+
return applyMark(mark, flattenChildren(type.schema, children))
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* @internal
|
|
156
|
+
*/
|
|
157
|
+
export type ApplyMarkFunction = (
|
|
158
|
+
mark: Mark,
|
|
159
|
+
children: ProseMirrorNode[],
|
|
160
|
+
) => ProseMirrorNode[]
|
|
161
|
+
|
|
162
|
+
const defaultApplyMark: ApplyMarkFunction = (
|
|
163
|
+
mark: Mark,
|
|
164
|
+
children: ProseMirrorNode[],
|
|
165
|
+
): ProseMirrorNode[] => {
|
|
166
|
+
return children.map((node) => node.mark(mark.addToSet(node.marks)))
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
function buildNode(
|
|
170
|
+
type: NodeType,
|
|
171
|
+
args: [Attrs | NodeChild | null | undefined, ...NodeChild[]],
|
|
172
|
+
createNode: CreateNodeFunction,
|
|
173
|
+
): ProseMirrorNode {
|
|
174
|
+
const [attrs, children] = normalizeArgs(args)
|
|
175
|
+
return createNode(type, attrs, flattenChildren(type.schema, children))
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* @internal
|
|
180
|
+
*/
|
|
181
|
+
export type CreateNodeFunction = (
|
|
182
|
+
type: NodeType,
|
|
183
|
+
attrs: Attrs | null,
|
|
184
|
+
children: ProseMirrorNode[],
|
|
185
|
+
) => ProseMirrorNode
|
|
186
|
+
|
|
187
|
+
type GetStateFunction = () => EditorState | null | undefined
|
|
188
|
+
|
|
189
|
+
const defaultCreateNode: CreateNodeFunction = (
|
|
190
|
+
type: NodeType,
|
|
191
|
+
attrs: Attrs | null,
|
|
192
|
+
children: ProseMirrorNode[],
|
|
193
|
+
) => {
|
|
194
|
+
const node = type.createAndFill(attrs, children)
|
|
195
|
+
assert(node, `Failed to create node ${type.name}`)
|
|
196
|
+
return node
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
function flattenChildren(
|
|
200
|
+
schema: Schema,
|
|
201
|
+
children: NodeChild[],
|
|
202
|
+
): Array<ProseMirrorNode> {
|
|
203
|
+
const nodes: Array<ProseMirrorNode> = []
|
|
204
|
+
|
|
205
|
+
for (const child of children) {
|
|
206
|
+
if (typeof child === 'string') {
|
|
207
|
+
if (child) {
|
|
208
|
+
nodes.push(schema.text(child, null))
|
|
209
|
+
}
|
|
210
|
+
} else if (Array.isArray(child)) {
|
|
211
|
+
nodes.push(...flattenChildren(schema, child))
|
|
212
|
+
} else if (isProseMirrorNode(child)) {
|
|
213
|
+
nodes.push(child)
|
|
214
|
+
} else {
|
|
215
|
+
throw new ProseKitError(`Invalid node child: ${typeof child}`)
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
return nodes
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
function normalizeArgs(
|
|
223
|
+
args: [Attrs | NodeChild | null | undefined, ...NodeChild[]],
|
|
224
|
+
): [Attrs | null, NodeChild[]] {
|
|
225
|
+
const [attrs, ...children] = args
|
|
226
|
+
if (isNodeChild(attrs)) {
|
|
227
|
+
children.unshift(attrs)
|
|
228
|
+
return [null, children]
|
|
229
|
+
} else if (typeof attrs === 'object') {
|
|
230
|
+
return [attrs, children]
|
|
231
|
+
} else {
|
|
232
|
+
return [null, children]
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
function isNodeChild(
|
|
237
|
+
value: Attrs | NodeChild | null | undefined,
|
|
238
|
+
): value is NodeChild {
|
|
239
|
+
if (!value) {
|
|
240
|
+
return false
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
return (
|
|
244
|
+
typeof value === 'string'
|
|
245
|
+
|| Array.isArray(value)
|
|
246
|
+
|| isProseMirrorNode(value)
|
|
247
|
+
)
|
|
248
|
+
}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import {
|
|
2
|
+
describe,
|
|
3
|
+
expect,
|
|
4
|
+
it,
|
|
5
|
+
} from 'vitest'
|
|
6
|
+
|
|
7
|
+
import { insertText } from '../commands/insert-text'
|
|
8
|
+
import { wrap } from '../commands/wrap'
|
|
9
|
+
import {
|
|
10
|
+
defineTestExtension,
|
|
11
|
+
setupTest,
|
|
12
|
+
} from '../testing'
|
|
13
|
+
import type { NodeJSON } from '../types/model'
|
|
14
|
+
|
|
15
|
+
import { createEditor } from './editor'
|
|
16
|
+
|
|
17
|
+
describe('createEditor', () => {
|
|
18
|
+
it('can mount the editor', () => {
|
|
19
|
+
const div = document.body.appendChild(document.createElement('div'))
|
|
20
|
+
const extension = defineTestExtension()
|
|
21
|
+
const editor = createEditor({ extension })
|
|
22
|
+
editor.mount(div)
|
|
23
|
+
expect(div.outerHTML).toMatchInlineSnapshot(
|
|
24
|
+
`"<div contenteditable="true" translate="no" class="ProseMirror"><p><br class="ProseMirror-trailingBreak"></p></div>"`,
|
|
25
|
+
)
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
it('can get and update state', () => {
|
|
29
|
+
const extension = defineTestExtension()
|
|
30
|
+
const editor = createEditor({ extension })
|
|
31
|
+
|
|
32
|
+
const update = (text: string) => {
|
|
33
|
+
const s1 = editor.state
|
|
34
|
+
const s2 = s1.apply(s1.tr.insertText(text, 1))
|
|
35
|
+
editor.updateState(s2)
|
|
36
|
+
const s3 = editor.state
|
|
37
|
+
|
|
38
|
+
expect(s3).toBe(s2)
|
|
39
|
+
expect(s2).not.toEqual(s1)
|
|
40
|
+
|
|
41
|
+
return s3
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const expectStateEqual = (fn: VoidFunction) => {
|
|
45
|
+
const s1 = editor.state
|
|
46
|
+
fn()
|
|
47
|
+
const s2 = editor.state
|
|
48
|
+
expect(s1).toBe(s2)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const expectStateNotEqual = (fn: VoidFunction) => {
|
|
52
|
+
const s1 = editor.state
|
|
53
|
+
fn()
|
|
54
|
+
const s2 = editor.state
|
|
55
|
+
expect(s1).not.toEqual(s2)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Initial state
|
|
59
|
+
expect(editor.state).toBeDefined()
|
|
60
|
+
expect(editor.state.doc.textContent).toMatchInlineSnapshot(`""`)
|
|
61
|
+
|
|
62
|
+
// Update state before mounting
|
|
63
|
+
expectStateNotEqual(() => update('1'))
|
|
64
|
+
expect(editor.state.doc.textContent).toMatchInlineSnapshot(`"1"`)
|
|
65
|
+
|
|
66
|
+
// Mount editor
|
|
67
|
+
const div = document.body.appendChild(document.createElement('div'))
|
|
68
|
+
expectStateEqual(() => editor.mount(div))
|
|
69
|
+
expect(editor.state.doc.textContent).toMatchInlineSnapshot(`"1"`)
|
|
70
|
+
|
|
71
|
+
// Update state after mounting
|
|
72
|
+
expectStateNotEqual(() => update('2'))
|
|
73
|
+
expect(editor.state.doc.textContent).toMatchInlineSnapshot(`"21"`)
|
|
74
|
+
|
|
75
|
+
// Unmount editor
|
|
76
|
+
expectStateEqual(() => editor.unmount())
|
|
77
|
+
expect(editor.state.doc.textContent).toMatchInlineSnapshot(`"21"`)
|
|
78
|
+
|
|
79
|
+
// Update state after unmounting
|
|
80
|
+
expectStateNotEqual(() => update('3'))
|
|
81
|
+
expect(editor.state.doc.textContent).toMatchInlineSnapshot(`"321"`)
|
|
82
|
+
|
|
83
|
+
// Re-mount editor
|
|
84
|
+
expectStateEqual(() => editor.mount(div))
|
|
85
|
+
expect(editor.state.doc.textContent).toMatchInlineSnapshot(`"321"`)
|
|
86
|
+
|
|
87
|
+
// Update state after re-mounting
|
|
88
|
+
expectStateNotEqual(() => update('4'))
|
|
89
|
+
expect(editor.state.doc.textContent).toMatchInlineSnapshot(`"4321"`)
|
|
90
|
+
})
|
|
91
|
+
|
|
92
|
+
it('can update document and selection', () => {
|
|
93
|
+
const extension = defineTestExtension()
|
|
94
|
+
const editor = createEditor({ extension })
|
|
95
|
+
|
|
96
|
+
expect(editor.state.doc.textContent).toMatchInlineSnapshot(`""`)
|
|
97
|
+
|
|
98
|
+
editor.setContent('foo')
|
|
99
|
+
expect(editor.state.toJSON()).toMatchInlineSnapshot(`
|
|
100
|
+
{
|
|
101
|
+
"doc": {
|
|
102
|
+
"content": [
|
|
103
|
+
{
|
|
104
|
+
"content": [
|
|
105
|
+
{
|
|
106
|
+
"text": "foo",
|
|
107
|
+
"type": "text",
|
|
108
|
+
},
|
|
109
|
+
],
|
|
110
|
+
"type": "paragraph",
|
|
111
|
+
},
|
|
112
|
+
],
|
|
113
|
+
"type": "doc",
|
|
114
|
+
},
|
|
115
|
+
"selection": {
|
|
116
|
+
"anchor": 1,
|
|
117
|
+
"head": 1,
|
|
118
|
+
"type": "text",
|
|
119
|
+
},
|
|
120
|
+
}
|
|
121
|
+
`)
|
|
122
|
+
|
|
123
|
+
editor.setContent(
|
|
124
|
+
{
|
|
125
|
+
type: 'doc',
|
|
126
|
+
content: [
|
|
127
|
+
{
|
|
128
|
+
type: 'paragraph',
|
|
129
|
+
content: [{ type: 'text', text: 'bar' }],
|
|
130
|
+
},
|
|
131
|
+
],
|
|
132
|
+
},
|
|
133
|
+
'end',
|
|
134
|
+
)
|
|
135
|
+
expect(editor.state.toJSON()).toMatchInlineSnapshot(`
|
|
136
|
+
{
|
|
137
|
+
"doc": {
|
|
138
|
+
"content": [
|
|
139
|
+
{
|
|
140
|
+
"content": [
|
|
141
|
+
{
|
|
142
|
+
"text": "bar",
|
|
143
|
+
"type": "text",
|
|
144
|
+
},
|
|
145
|
+
],
|
|
146
|
+
"type": "paragraph",
|
|
147
|
+
},
|
|
148
|
+
],
|
|
149
|
+
"type": "doc",
|
|
150
|
+
},
|
|
151
|
+
"selection": {
|
|
152
|
+
"anchor": 4,
|
|
153
|
+
"head": 4,
|
|
154
|
+
"type": "text",
|
|
155
|
+
},
|
|
156
|
+
}
|
|
157
|
+
`)
|
|
158
|
+
})
|
|
159
|
+
|
|
160
|
+
it('can refuse invalid document', () => {
|
|
161
|
+
const extension = defineTestExtension()
|
|
162
|
+
const editor = createEditor({ extension })
|
|
163
|
+
|
|
164
|
+
const invalidDoc: NodeJSON = {
|
|
165
|
+
type: 'doc',
|
|
166
|
+
content: [{ type: 'text', text: 'bar aaa aa' }],
|
|
167
|
+
}
|
|
168
|
+
expect(() => editor.setContent(invalidDoc)).toThrow()
|
|
169
|
+
})
|
|
170
|
+
|
|
171
|
+
it('can execute commands', () => {
|
|
172
|
+
const { editor } = setupTest()
|
|
173
|
+
|
|
174
|
+
expect(editor.exec(insertText({ text: 'foo' }))).toBe(true)
|
|
175
|
+
expect(editor.state.doc.textContent).toBe('foo')
|
|
176
|
+
|
|
177
|
+
expect(editor.commands.insertText({ text: 'bar' })).toBe(true)
|
|
178
|
+
expect(editor.state.doc.textContent).toBe('foobar')
|
|
179
|
+
|
|
180
|
+
expect(editor.exec(wrap({ type: 'paragraph' }))).toBe(false)
|
|
181
|
+
expect(editor.commands.wrap({ type: 'paragraph' })).toBe(false)
|
|
182
|
+
|
|
183
|
+
expect(editor.canExec(wrap({ type: 'paragraph' }))).toBe(false)
|
|
184
|
+
expect(editor.commands.wrap.canExec({ type: 'paragraph' })).toBe(false)
|
|
185
|
+
})
|
|
186
|
+
})
|