@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.
Files changed (168) hide show
  1. package/dist/editor-CfkZ4TNU.d.ts +748 -0
  2. package/dist/editor-CfkZ4TNU.d.ts.map +1 -0
  3. package/dist/{editor-DlGlYOp-.js → editor-CizSwUN8.js} +76 -168
  4. package/dist/editor-CizSwUN8.js.map +1 -0
  5. package/dist/prosekit-core-test.d.ts +20 -19
  6. package/dist/prosekit-core-test.d.ts.map +1 -0
  7. package/dist/prosekit-core-test.js +4 -5
  8. package/dist/prosekit-core-test.js.map +1 -0
  9. package/dist/prosekit-core.d.ts +766 -743
  10. package/dist/prosekit-core.d.ts.map +1 -0
  11. package/dist/prosekit-core.js +26 -43
  12. package/dist/prosekit-core.js.map +1 -0
  13. package/package.json +12 -9
  14. package/src/commands/add-mark.ts +53 -0
  15. package/src/commands/expand-mark.ts +96 -0
  16. package/src/commands/insert-default-block.spec.ts +102 -0
  17. package/src/commands/insert-default-block.ts +49 -0
  18. package/src/commands/insert-node.ts +71 -0
  19. package/src/commands/insert-text.ts +24 -0
  20. package/src/commands/remove-mark.ts +54 -0
  21. package/src/commands/remove-node.ts +43 -0
  22. package/src/commands/select-all.ts +16 -0
  23. package/src/commands/set-block-type.ts +64 -0
  24. package/src/commands/set-node-attrs.ts +68 -0
  25. package/src/commands/toggle-mark.ts +65 -0
  26. package/src/commands/toggle-node.ts +47 -0
  27. package/src/commands/toggle-wrap.spec.ts +35 -0
  28. package/src/commands/toggle-wrap.ts +42 -0
  29. package/src/commands/unset-block-type.spec.ts +49 -0
  30. package/src/commands/unset-block-type.ts +84 -0
  31. package/src/commands/unset-mark.spec.ts +35 -0
  32. package/src/commands/unset-mark.ts +38 -0
  33. package/src/commands/wrap.ts +50 -0
  34. package/src/editor/action.spec.ts +143 -0
  35. package/src/editor/action.ts +248 -0
  36. package/src/editor/editor.spec.ts +186 -0
  37. package/src/editor/editor.ts +563 -0
  38. package/src/editor/union.spec.ts +108 -0
  39. package/src/editor/union.ts +47 -0
  40. package/src/editor/with-priority.ts +25 -0
  41. package/src/error.ts +28 -0
  42. package/src/extensions/clipboard-serializer.ts +107 -0
  43. package/src/extensions/command.ts +121 -0
  44. package/src/extensions/default-state.spec.ts +60 -0
  45. package/src/extensions/default-state.ts +76 -0
  46. package/src/extensions/doc.ts +31 -0
  47. package/src/extensions/events/doc-change.ts +34 -0
  48. package/src/extensions/events/dom-event.spec.ts +70 -0
  49. package/src/extensions/events/dom-event.ts +117 -0
  50. package/src/extensions/events/editor-event.ts +293 -0
  51. package/src/extensions/events/focus.spec.ts +50 -0
  52. package/src/extensions/events/focus.ts +28 -0
  53. package/src/extensions/events/plugin-view.ts +132 -0
  54. package/src/extensions/history.ts +81 -0
  55. package/src/extensions/keymap-base.ts +60 -0
  56. package/src/extensions/keymap.spec.ts +89 -0
  57. package/src/extensions/keymap.ts +96 -0
  58. package/src/extensions/mark-spec.spec.ts +177 -0
  59. package/src/extensions/mark-spec.ts +181 -0
  60. package/src/extensions/mark-view-effect.ts +85 -0
  61. package/src/extensions/mark-view.ts +43 -0
  62. package/src/extensions/node-spec.spec.ts +224 -0
  63. package/src/extensions/node-spec.ts +199 -0
  64. package/src/extensions/node-view-effect.ts +85 -0
  65. package/src/extensions/node-view.ts +43 -0
  66. package/src/extensions/paragraph.ts +61 -0
  67. package/src/extensions/plugin.ts +91 -0
  68. package/src/extensions/text.ts +34 -0
  69. package/src/facets/base-extension.ts +54 -0
  70. package/src/facets/command.ts +21 -0
  71. package/src/facets/facet-extension.spec.ts +173 -0
  72. package/src/facets/facet-extension.ts +53 -0
  73. package/src/facets/facet-node.spec.ts +265 -0
  74. package/src/facets/facet-node.ts +185 -0
  75. package/src/facets/facet-types.ts +9 -0
  76. package/src/facets/facet.spec.ts +76 -0
  77. package/src/facets/facet.ts +84 -0
  78. package/src/facets/root.ts +44 -0
  79. package/src/facets/schema-spec.ts +30 -0
  80. package/src/facets/schema.ts +26 -0
  81. package/src/facets/state.ts +57 -0
  82. package/src/facets/union-extension.ts +41 -0
  83. package/src/index.ts +302 -0
  84. package/src/test/index.ts +4 -0
  85. package/src/test/test-builder.ts +68 -0
  86. package/src/test/test-editor.spec.ts +104 -0
  87. package/src/test/test-editor.ts +113 -0
  88. package/src/testing/index.ts +283 -0
  89. package/src/testing/keyboard.ts +5 -0
  90. package/src/types/any-function.ts +4 -0
  91. package/src/types/assert-type-equal.ts +8 -0
  92. package/src/types/attrs.ts +32 -0
  93. package/src/types/base-node-view-options.ts +33 -0
  94. package/src/types/dom-node.ts +1 -0
  95. package/src/types/extension-command.ts +52 -0
  96. package/src/types/extension-mark.ts +15 -0
  97. package/src/types/extension-node.ts +15 -0
  98. package/src/types/extension.spec.ts +56 -0
  99. package/src/types/extension.ts +168 -0
  100. package/src/types/model.ts +54 -0
  101. package/src/types/object-entries.ts +13 -0
  102. package/src/types/pick-string-literal.spec.ts +10 -0
  103. package/src/types/pick-string-literal.ts +6 -0
  104. package/src/types/pick-sub-type.spec.ts +20 -0
  105. package/src/types/pick-sub-type.ts +6 -0
  106. package/src/types/priority.ts +12 -0
  107. package/src/types/setter.ts +4 -0
  108. package/src/types/simplify-deeper.spec.ts +40 -0
  109. package/src/types/simplify-deeper.ts +6 -0
  110. package/src/types/simplify-union.spec.ts +21 -0
  111. package/src/types/simplify-union.ts +11 -0
  112. package/src/utils/array-grouping.spec.ts +29 -0
  113. package/src/utils/array-grouping.ts +25 -0
  114. package/src/utils/array.ts +21 -0
  115. package/src/utils/assert.ts +13 -0
  116. package/src/utils/attrs-match.ts +20 -0
  117. package/src/utils/can-use-regex-lookbehind.ts +12 -0
  118. package/src/utils/clsx.spec.ts +14 -0
  119. package/src/utils/clsx.ts +12 -0
  120. package/src/utils/collect-children.ts +21 -0
  121. package/src/utils/collect-nodes.ts +37 -0
  122. package/src/utils/combine-event-handlers.spec.ts +27 -0
  123. package/src/utils/combine-event-handlers.ts +27 -0
  124. package/src/utils/contains-inline-node.ts +17 -0
  125. package/src/utils/deep-equals.spec.ts +26 -0
  126. package/src/utils/deep-equals.ts +29 -0
  127. package/src/utils/default-block-at.ts +15 -0
  128. package/src/utils/editor-content.spec.ts +47 -0
  129. package/src/utils/editor-content.ts +77 -0
  130. package/src/utils/env.ts +6 -0
  131. package/src/utils/find-parent-node-of-type.ts +29 -0
  132. package/src/utils/find-parent-node.spec.ts +68 -0
  133. package/src/utils/find-parent-node.ts +55 -0
  134. package/src/utils/get-custom-selection.ts +19 -0
  135. package/src/utils/get-dom-api.ts +56 -0
  136. package/src/utils/get-id.spec.ts +14 -0
  137. package/src/utils/get-id.ts +13 -0
  138. package/src/utils/get-mark-type.ts +20 -0
  139. package/src/utils/get-node-type.ts +20 -0
  140. package/src/utils/get-node-types.ts +19 -0
  141. package/src/utils/includes-mark.ts +18 -0
  142. package/src/utils/is-at-block-start.ts +26 -0
  143. package/src/utils/is-in-code-block.ts +18 -0
  144. package/src/utils/is-mark-absent.spec.ts +53 -0
  145. package/src/utils/is-mark-absent.ts +42 -0
  146. package/src/utils/is-mark-active.ts +27 -0
  147. package/src/utils/is-node-active.ts +25 -0
  148. package/src/utils/is-subset.spec.ts +12 -0
  149. package/src/utils/is-subset.ts +11 -0
  150. package/src/utils/maybe-run.spec.ts +39 -0
  151. package/src/utils/maybe-run.ts +11 -0
  152. package/src/utils/merge-objects.spec.ts +30 -0
  153. package/src/utils/merge-objects.ts +11 -0
  154. package/src/utils/merge-specs.ts +35 -0
  155. package/src/utils/object-equal.spec.ts +26 -0
  156. package/src/utils/object-equal.ts +28 -0
  157. package/src/utils/output-spec.test.ts +95 -0
  158. package/src/utils/output-spec.ts +130 -0
  159. package/src/utils/parse.spec.ts +46 -0
  160. package/src/utils/parse.ts +321 -0
  161. package/src/utils/remove-undefined-values.spec.ts +15 -0
  162. package/src/utils/remove-undefined-values.ts +9 -0
  163. package/src/utils/set-selection-around.ts +11 -0
  164. package/src/utils/type-assertion.ts +91 -0
  165. package/src/utils/unicode.spec.ts +10 -0
  166. package/src/utils/unicode.ts +4 -0
  167. package/src/utils/with-skip-code-block.ts +15 -0
  168. 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
+ })