@prosekit/core 0.8.7 → 0.9.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.
- package/dist/{editor-M9OimMiI.d.ts → editor-4lgGc3CY.d.ts} +20 -60
- package/dist/editor-4lgGc3CY.d.ts.map +1 -0
- package/dist/{editor-B0L9BgMi.js → editor-DGNUXn-u.js} +98 -115
- package/dist/editor-DGNUXn-u.js.map +1 -0
- package/dist/prosekit-core-test.d.ts +1 -1
- package/dist/prosekit-core-test.js +1 -1
- package/dist/prosekit-core.d.ts +81 -180
- package/dist/prosekit-core.d.ts.map +1 -1
- package/dist/prosekit-core.js +316 -403
- package/dist/prosekit-core.js.map +1 -1
- package/package.json +8 -10
- package/src/commands/select-all.ts +3 -8
- package/src/commands/select-block.spec.ts +83 -0
- package/src/commands/select-block.ts +59 -0
- package/src/commands/wrap.ts +1 -6
- package/src/editor/action.ts +1 -11
- package/src/editor/editor.ts +20 -32
- package/src/extensions/command.ts +4 -0
- package/src/extensions/default-state.spec.ts +0 -4
- package/src/extensions/default-state.ts +4 -24
- package/src/extensions/events/dom-event.ts +1 -4
- package/src/extensions/events/editor-event.ts +1 -1
- package/src/extensions/history.ts +1 -1
- package/src/extensions/keymap-base.spec.ts +98 -0
- package/src/extensions/keymap-base.ts +37 -13
- package/src/extensions/keymap.spec.ts +9 -5
- package/src/extensions/keymap.ts +13 -56
- package/src/extensions/mark-spec.ts +32 -29
- package/src/extensions/node-spec.ts +28 -19
- package/src/extensions/plugin.ts +1 -2
- package/src/facets/command.ts +8 -2
- package/src/facets/state.spec.ts +6 -6
- package/src/facets/state.ts +1 -2
- package/src/index.ts +3 -23
- package/src/types/extension-command.ts +0 -7
- package/src/types/extension.ts +0 -16
- package/src/utils/array-grouping.spec.ts +1 -11
- package/src/utils/array-grouping.ts +1 -14
- package/src/utils/array.ts +0 -4
- package/src/utils/combine-event-handlers.ts +4 -6
- package/src/utils/editor-content.ts +3 -3
- package/src/utils/output-spec.ts +11 -0
- package/src/utils/parse.ts +9 -9
- package/dist/editor-B0L9BgMi.js.map +0 -1
- package/dist/editor-M9OimMiI.d.ts.map +0 -1
- package/src/extensions/doc.ts +0 -31
- package/src/extensions/paragraph.ts +0 -61
- package/src/extensions/text.ts +0 -34
- package/src/types/base-node-view-options.ts +0 -33
- package/src/types/object-entries.ts +0 -13
- package/src/utils/collect-children.ts +0 -21
- package/src/utils/collect-nodes.ts +0 -37
- package/src/utils/deep-equals.spec.ts +0 -26
- package/src/utils/deep-equals.ts +0 -29
- package/src/utils/get-id.spec.ts +0 -14
- package/src/utils/get-id.ts +0 -13
|
@@ -6,15 +6,20 @@ import {
|
|
|
6
6
|
joinTextblockBackward,
|
|
7
7
|
liftEmptyBlock,
|
|
8
8
|
newlineInCode,
|
|
9
|
+
selectAll,
|
|
9
10
|
selectNodeBackward,
|
|
10
11
|
} from '@prosekit/pm/commands'
|
|
11
12
|
import { splitSplittableBlock } from 'prosemirror-splittable'
|
|
12
13
|
|
|
14
|
+
import { selectBlockCommand } from '../commands/select-block'
|
|
13
15
|
import { withPriority } from '../editor/with-priority'
|
|
14
16
|
import type { PlainExtension } from '../types/extension'
|
|
15
17
|
import { Priority } from '../types/priority'
|
|
16
18
|
|
|
17
|
-
import {
|
|
19
|
+
import {
|
|
20
|
+
defineKeymap,
|
|
21
|
+
type Keymap,
|
|
22
|
+
} from './keymap'
|
|
18
23
|
|
|
19
24
|
// Replace `splitBlock` with `splitSplittableBlock`
|
|
20
25
|
const customEnter = chainCommands(
|
|
@@ -31,30 +36,49 @@ const customBackspace = chainCommands(
|
|
|
31
36
|
selectNodeBackward,
|
|
32
37
|
)
|
|
33
38
|
|
|
34
|
-
const customBaseKeymap = {
|
|
35
|
-
...baseKeymap,
|
|
36
|
-
Enter: customEnter,
|
|
37
|
-
Backspace: customBackspace,
|
|
38
|
-
}
|
|
39
|
-
|
|
40
39
|
/**
|
|
41
40
|
* @internal
|
|
42
41
|
*/
|
|
43
42
|
export type BaseKeymapExtension = PlainExtension
|
|
44
43
|
|
|
45
44
|
/**
|
|
46
|
-
* Defines some basic key bindings.
|
|
47
|
-
*
|
|
48
45
|
* @public
|
|
49
46
|
*/
|
|
50
|
-
export
|
|
47
|
+
export interface BaseKeymapOptions {
|
|
51
48
|
/**
|
|
52
49
|
* The priority of the keymap.
|
|
53
50
|
*
|
|
54
51
|
* @default Priority.low
|
|
55
52
|
*/
|
|
56
53
|
priority?: Priority
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* If `true`, the first `Mod-a` press selects the current block that the
|
|
57
|
+
* cursor is in, and a second press selects the entire document.
|
|
58
|
+
*
|
|
59
|
+
* If `false`, `Mod-a` immediately selects the entire document.
|
|
60
|
+
*
|
|
61
|
+
* @default true
|
|
62
|
+
*/
|
|
63
|
+
preferBlockSelection?: boolean
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Defines some basic key bindings.
|
|
68
|
+
*
|
|
69
|
+
* @param options
|
|
70
|
+
*
|
|
71
|
+
* @public
|
|
72
|
+
*/
|
|
73
|
+
export function defineBaseKeymap({
|
|
74
|
+
priority = Priority.low,
|
|
75
|
+
preferBlockSelection = true,
|
|
76
|
+
}: BaseKeymapOptions = {}): BaseKeymapExtension {
|
|
77
|
+
const keymap: Keymap = {
|
|
78
|
+
...baseKeymap,
|
|
79
|
+
'Mod-a': preferBlockSelection ? chainCommands(selectBlockCommand, selectAll) : selectAll,
|
|
80
|
+
'Enter': customEnter,
|
|
81
|
+
'Backspace': customBackspace,
|
|
82
|
+
}
|
|
83
|
+
return withPriority(defineKeymap(keymap), priority)
|
|
60
84
|
}
|
|
@@ -159,9 +159,13 @@ describe('keymap', () => {
|
|
|
159
159
|
// Do not match
|
|
160
160
|
'ctrl-c',
|
|
161
161
|
]
|
|
162
|
-
const keymap: Keymap = Object.fromEntries(keybindings.map(binding => [binding, record(binding)]))
|
|
163
162
|
|
|
164
|
-
|
|
163
|
+
for (const key of keybindings) {
|
|
164
|
+
let command: Command = record(key)
|
|
165
|
+
let keymap: Keymap = { [key]: command }
|
|
166
|
+
let extension = defineKeymap(keymap)
|
|
167
|
+
editor.use(extension)
|
|
168
|
+
}
|
|
165
169
|
|
|
166
170
|
called.length = 0
|
|
167
171
|
await keyboard.down('Control')
|
|
@@ -170,8 +174,8 @@ describe('keymap', () => {
|
|
|
170
174
|
await keyboard.up('Control')
|
|
171
175
|
expect(called).toMatchInlineSnapshot(`
|
|
172
176
|
[
|
|
173
|
-
"ctrl-b",
|
|
174
177
|
"CTRL-b",
|
|
178
|
+
"ctrl-b",
|
|
175
179
|
]
|
|
176
180
|
`)
|
|
177
181
|
|
|
@@ -184,10 +188,10 @@ describe('keymap', () => {
|
|
|
184
188
|
await keyboard.up('Control')
|
|
185
189
|
expect(called).toMatchInlineSnapshot(`
|
|
186
190
|
[
|
|
187
|
-
"c-s-B",
|
|
188
|
-
"c-B",
|
|
189
191
|
"Ctrl-B",
|
|
192
|
+
"c-s-B",
|
|
190
193
|
"ctrl-shift-b",
|
|
194
|
+
"c-B",
|
|
191
195
|
]
|
|
192
196
|
`)
|
|
193
197
|
})
|
package/src/extensions/keymap.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { chainCommands } from '@prosekit/pm/commands'
|
|
2
1
|
import { keydownHandler } from '@prosekit/pm/keymap'
|
|
3
2
|
import {
|
|
4
3
|
Plugin,
|
|
@@ -6,7 +5,6 @@ import {
|
|
|
6
5
|
type Command,
|
|
7
6
|
} from '@prosekit/pm/state'
|
|
8
7
|
import type { EditorView } from '@prosekit/pm/view'
|
|
9
|
-
import mapValues from 'just-map-values'
|
|
10
8
|
|
|
11
9
|
import {
|
|
12
10
|
defineFacet,
|
|
@@ -14,8 +12,6 @@ import {
|
|
|
14
12
|
} from '../facets/facet'
|
|
15
13
|
import { defineFacetPayload } from '../facets/facet-extension'
|
|
16
14
|
import type { PlainExtension } from '../types/extension'
|
|
17
|
-
import { toReversed } from '../utils/array'
|
|
18
|
-
import { isApple } from '../utils/env'
|
|
19
15
|
|
|
20
16
|
import {
|
|
21
17
|
pluginFacet,
|
|
@@ -55,27 +51,29 @@ export const keymapFacet: Facet<KeymapPayload, PluginPayload> = defineFacet<
|
|
|
55
51
|
PluginPayload
|
|
56
52
|
>({
|
|
57
53
|
reduce: () => {
|
|
58
|
-
type
|
|
54
|
+
type KeydownHandler = (view: EditorView, event: KeyboardEvent) => boolean
|
|
59
55
|
|
|
60
|
-
|
|
56
|
+
// An array of keymap handlers, ordered from the highest priority to the lowest.
|
|
57
|
+
let subHandlers: KeydownHandler[] = []
|
|
61
58
|
|
|
62
|
-
|
|
63
|
-
|
|
59
|
+
// A root handler that combines all the sub handlers.
|
|
60
|
+
const rootHandler: KeydownHandler = (view, event) => {
|
|
61
|
+
for (const handler of subHandlers) {
|
|
62
|
+
if (handler(view, event)) return true
|
|
63
|
+
}
|
|
64
64
|
return false
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
const plugin = new Plugin({
|
|
68
68
|
key: keymapPluginKey,
|
|
69
|
-
props: { handleKeyDown:
|
|
69
|
+
props: { handleKeyDown: rootHandler },
|
|
70
70
|
})
|
|
71
71
|
|
|
72
72
|
return (keymaps: Keymap[]) => {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
),
|
|
78
|
-
)
|
|
73
|
+
// The keymap at the end has a higher priority, so we need to reverse the
|
|
74
|
+
// order here.
|
|
75
|
+
subHandlers = keymaps.map(keydownHandler).reverse()
|
|
76
|
+
|
|
79
77
|
return plugin
|
|
80
78
|
}
|
|
81
79
|
},
|
|
@@ -83,45 +81,4 @@ export const keymapFacet: Facet<KeymapPayload, PluginPayload> = defineFacet<
|
|
|
83
81
|
singleton: true,
|
|
84
82
|
})
|
|
85
83
|
|
|
86
|
-
function mergeKeymaps(keymaps: Keymap[]): Keymap {
|
|
87
|
-
const bindings: Record<string, Command[]> = {}
|
|
88
|
-
|
|
89
|
-
for (const keymap of keymaps) {
|
|
90
|
-
for (const [key, command] of Object.entries(keymap)) {
|
|
91
|
-
const normalizedKey = normalizeKeyName(key)
|
|
92
|
-
const commands = bindings[normalizedKey] ||= []
|
|
93
|
-
commands.push(command)
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
return mapValues(bindings, mergeCommands)
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
function mergeCommands(commands: Command[]): Command {
|
|
101
|
-
return chainCommands(...commands)
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
// Copied from https://github.com/ProseMirror/prosemirror-keymap/blob/1.2.3/src/keymap.ts#L8
|
|
105
|
-
function normalizeKeyName(name: string) {
|
|
106
|
-
let parts = name.split(/-(?!$)/), result = parts[parts.length - 1]
|
|
107
|
-
if (result == 'Space') result = ' '
|
|
108
|
-
let alt, ctrl, shift, meta
|
|
109
|
-
for (let i = 0; i < parts.length - 1; i++) {
|
|
110
|
-
let mod = parts[i]
|
|
111
|
-
if (/^(cmd|meta|m)$/i.test(mod)) meta = true
|
|
112
|
-
else if (/^a(lt)?$/i.test(mod)) alt = true
|
|
113
|
-
else if (/^(c|ctrl|control)$/i.test(mod)) ctrl = true
|
|
114
|
-
else if (/^s(hift)?$/i.test(mod)) shift = true
|
|
115
|
-
else if (/^mod$/i.test(mod)) {
|
|
116
|
-
if (isApple) meta = true
|
|
117
|
-
else ctrl = true
|
|
118
|
-
} else throw new Error('Unrecognized modifier name: ' + mod)
|
|
119
|
-
}
|
|
120
|
-
if (alt) result = 'Alt-' + result
|
|
121
|
-
if (ctrl) result = 'Ctrl-' + result
|
|
122
|
-
if (meta) result = 'Meta-' + result
|
|
123
|
-
if (shift) result = 'Shift-' + result
|
|
124
|
-
return result
|
|
125
|
-
}
|
|
126
|
-
|
|
127
84
|
const keymapPluginKey = new PluginKey('prosekit-keymap')
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
+
import { mapGroupBy } from '@ocavue/utils'
|
|
1
2
|
import type {
|
|
3
|
+
AttributeSpec,
|
|
2
4
|
MarkSpec,
|
|
3
|
-
ParseRule,
|
|
4
5
|
SchemaSpec,
|
|
5
6
|
} from '@prosekit/pm/model'
|
|
6
|
-
import clone from 'just-clone'
|
|
7
7
|
import OrderedMap from 'orderedmap'
|
|
8
8
|
|
|
9
9
|
import { defineFacet } from '../facets/facet'
|
|
@@ -14,12 +14,11 @@ import type {
|
|
|
14
14
|
AttrSpec,
|
|
15
15
|
} from '../types/attrs'
|
|
16
16
|
import type { Extension } from '../types/extension'
|
|
17
|
-
import { groupBy } from '../utils/array-grouping'
|
|
18
17
|
import { assert } from '../utils/assert'
|
|
19
18
|
import { mergeSpecs } from '../utils/merge-specs'
|
|
20
19
|
import {
|
|
21
20
|
wrapOutputSpecAttrs,
|
|
22
|
-
|
|
21
|
+
wrapParseRuleAttrs,
|
|
23
22
|
} from '../utils/output-spec'
|
|
24
23
|
import { isNotNullish } from '../utils/type-assertion'
|
|
25
24
|
|
|
@@ -76,7 +75,24 @@ export interface MarkAttrOptions<
|
|
|
76
75
|
}
|
|
77
76
|
|
|
78
77
|
/**
|
|
78
|
+
* Defines a mark type into the editor schema.
|
|
79
|
+
*
|
|
79
80
|
* @public
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
*
|
|
84
|
+
* ```ts
|
|
85
|
+
* const extension = defineMarkSpec({
|
|
86
|
+
* name: 'bold',
|
|
87
|
+
* parseDOM: [
|
|
88
|
+
* { tag: 'strong' },
|
|
89
|
+
* { tag: 'b' },
|
|
90
|
+
* ],
|
|
91
|
+
* toDOM() {
|
|
92
|
+
* return ['strong', 0]
|
|
93
|
+
* },
|
|
94
|
+
* })
|
|
95
|
+
* ```
|
|
80
96
|
*/
|
|
81
97
|
export function defineMarkSpec<
|
|
82
98
|
Mark extends string,
|
|
@@ -133,35 +149,32 @@ const markSpecFacet = defineFacet<MarkSpecPayload, SchemaSpec>({
|
|
|
133
149
|
}
|
|
134
150
|
}
|
|
135
151
|
|
|
136
|
-
const groupedAttrs =
|
|
152
|
+
const groupedAttrs = mapGroupBy(attrPayloads, (payload) => payload.type)
|
|
137
153
|
|
|
138
|
-
for (const [type, attrs] of
|
|
154
|
+
for (const [type, attrs] of groupedAttrs.entries()) {
|
|
139
155
|
if (!attrs) continue
|
|
140
156
|
|
|
141
|
-
const
|
|
142
|
-
assert(
|
|
143
|
-
const spec = clone(maybeSpec)
|
|
157
|
+
const oldSpec = specs.get(type)
|
|
158
|
+
assert(oldSpec, `Mark type ${type} must be defined`)
|
|
144
159
|
|
|
145
|
-
|
|
146
|
-
spec.attrs = {}
|
|
147
|
-
}
|
|
160
|
+
const newSpec = { ...oldSpec, attrs: { ...oldSpec.attrs } } satisfies MarkSpec
|
|
148
161
|
|
|
149
162
|
for (const attr of attrs) {
|
|
150
|
-
|
|
163
|
+
newSpec.attrs[attr.attr] = {
|
|
151
164
|
default: attr.default as unknown,
|
|
152
165
|
validate: attr.validate,
|
|
153
|
-
}
|
|
166
|
+
} satisfies AttributeSpec
|
|
154
167
|
}
|
|
155
168
|
|
|
156
|
-
if (
|
|
157
|
-
|
|
169
|
+
if (oldSpec.toDOM) {
|
|
170
|
+
newSpec.toDOM = wrapOutputSpecAttrs(oldSpec.toDOM, attrs)
|
|
158
171
|
}
|
|
159
172
|
|
|
160
|
-
if (
|
|
161
|
-
|
|
173
|
+
if (oldSpec.parseDOM) {
|
|
174
|
+
newSpec.parseDOM = oldSpec.parseDOM.map((rule) => wrapParseRuleAttrs(rule, attrs))
|
|
162
175
|
}
|
|
163
176
|
|
|
164
|
-
specs = specs.update(type,
|
|
177
|
+
specs = specs.update(type, newSpec)
|
|
165
178
|
}
|
|
166
179
|
|
|
167
180
|
return { marks: specs, nodes: {} }
|
|
@@ -169,13 +182,3 @@ const markSpecFacet = defineFacet<MarkSpecPayload, SchemaSpec>({
|
|
|
169
182
|
parent: schemaSpecFacet,
|
|
170
183
|
singleton: true,
|
|
171
184
|
})
|
|
172
|
-
|
|
173
|
-
function wrapParseRuleAttrs(
|
|
174
|
-
rule: ParseRule,
|
|
175
|
-
attrs: MarkAttrOptions[],
|
|
176
|
-
): ParseRule {
|
|
177
|
-
if (rule.tag) {
|
|
178
|
-
return wrapTagParseRuleAttrs(rule, attrs)
|
|
179
|
-
}
|
|
180
|
-
return rule
|
|
181
|
-
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
+
import { mapGroupBy } from '@ocavue/utils'
|
|
1
2
|
import type {
|
|
2
3
|
AttributeSpec,
|
|
3
4
|
NodeSpec,
|
|
4
5
|
SchemaSpec,
|
|
5
6
|
} from '@prosekit/pm/model'
|
|
6
|
-
import clone from 'just-clone'
|
|
7
7
|
import OrderedMap from 'orderedmap'
|
|
8
8
|
|
|
9
9
|
import { defineFacet } from '../facets/facet'
|
|
@@ -14,7 +14,6 @@ import type {
|
|
|
14
14
|
AttrSpec,
|
|
15
15
|
} from '../types/attrs'
|
|
16
16
|
import type { Extension } from '../types/extension'
|
|
17
|
-
import { groupBy } from '../utils/array-grouping'
|
|
18
17
|
import { assert } from '../utils/assert'
|
|
19
18
|
import { mergeSpecs } from '../utils/merge-specs'
|
|
20
19
|
import {
|
|
@@ -93,9 +92,23 @@ export interface NodeAttrOptions<
|
|
|
93
92
|
}
|
|
94
93
|
|
|
95
94
|
/**
|
|
96
|
-
* Defines a node type.
|
|
95
|
+
* Defines a node type into the editor schema.
|
|
97
96
|
*
|
|
98
97
|
* @public
|
|
98
|
+
*
|
|
99
|
+
* @example
|
|
100
|
+
*
|
|
101
|
+
* ```ts
|
|
102
|
+
* const extension = defineNodeSpec({
|
|
103
|
+
* name: 'fancyParagraph',
|
|
104
|
+
* content: 'inline*',
|
|
105
|
+
* group: 'block',
|
|
106
|
+
* parseDOM: [{ tag: 'p.fancy' }],
|
|
107
|
+
* toDOM() {
|
|
108
|
+
* return ['p', { 'class': 'fancy' }, 0]
|
|
109
|
+
* },
|
|
110
|
+
* })
|
|
111
|
+
* ```
|
|
99
112
|
*/
|
|
100
113
|
export function defineNodeSpec<
|
|
101
114
|
Node extends string,
|
|
@@ -159,37 +172,33 @@ const nodeSpecFacet = defineFacet<NodeSpecPayload, SchemaSpec>({
|
|
|
159
172
|
}
|
|
160
173
|
}
|
|
161
174
|
|
|
162
|
-
const groupedAttrs =
|
|
175
|
+
const groupedAttrs = mapGroupBy(attrPayloads, (payload) => payload.type)
|
|
163
176
|
|
|
164
|
-
for (const [type, attrs] of
|
|
177
|
+
for (const [type, attrs] of groupedAttrs.entries()) {
|
|
165
178
|
if (!attrs) continue
|
|
166
179
|
|
|
167
|
-
const
|
|
168
|
-
assert(
|
|
180
|
+
const oldSpec = specs.get(type)
|
|
181
|
+
assert(oldSpec, `Node type ${type} must be defined`)
|
|
169
182
|
|
|
170
|
-
const
|
|
171
|
-
|
|
172
|
-
if (!spec.attrs) {
|
|
173
|
-
spec.attrs = {}
|
|
174
|
-
}
|
|
183
|
+
const newSpec = { ...oldSpec, attrs: { ...oldSpec.attrs } } satisfies NodeSpec
|
|
175
184
|
|
|
176
185
|
for (const attr of attrs) {
|
|
177
|
-
|
|
186
|
+
newSpec.attrs[attr.attr] = {
|
|
178
187
|
default: attr.default as unknown,
|
|
179
188
|
validate: attr.validate,
|
|
180
189
|
splittable: attr.splittable,
|
|
181
|
-
}
|
|
190
|
+
} satisfies AttributeSpec
|
|
182
191
|
}
|
|
183
192
|
|
|
184
|
-
if (
|
|
185
|
-
|
|
193
|
+
if (oldSpec.toDOM) {
|
|
194
|
+
newSpec.toDOM = wrapOutputSpecAttrs(oldSpec.toDOM, attrs)
|
|
186
195
|
}
|
|
187
196
|
|
|
188
|
-
if (
|
|
189
|
-
|
|
197
|
+
if (oldSpec.parseDOM) {
|
|
198
|
+
newSpec.parseDOM = oldSpec.parseDOM.map((rule) => wrapTagParseRuleAttrs(rule, attrs))
|
|
190
199
|
}
|
|
191
200
|
|
|
192
|
-
specs = specs.update(type,
|
|
201
|
+
specs = specs.update(type, newSpec)
|
|
193
202
|
}
|
|
194
203
|
|
|
195
204
|
return { nodes: specs, topNode: topNodeName }
|
package/src/extensions/plugin.ts
CHANGED
|
@@ -15,7 +15,6 @@ import {
|
|
|
15
15
|
type StatePayload,
|
|
16
16
|
} from '../facets/state'
|
|
17
17
|
import type { PlainExtension } from '../types/extension'
|
|
18
|
-
import { toReversed } from '../utils/array'
|
|
19
18
|
|
|
20
19
|
/**
|
|
21
20
|
* Adds a ProseMirror plugin to the editor.
|
|
@@ -72,7 +71,7 @@ export const pluginFacet: Facet<PluginPayload, StatePayload> = defineFacet({
|
|
|
72
71
|
|
|
73
72
|
// An array of plugins from higher to lower priority. This matches the
|
|
74
73
|
// order of plugins required by ProseMirror.
|
|
75
|
-
const reversedPlugins =
|
|
74
|
+
const reversedPlugins = [...plugins].reverse()
|
|
76
75
|
|
|
77
76
|
return { plugins: reversedPlugins }
|
|
78
77
|
}
|
package/src/facets/command.ts
CHANGED
|
@@ -13,8 +13,14 @@ type CommandPayload = CommandCreators
|
|
|
13
13
|
|
|
14
14
|
export const commandFacet: Facet<CommandPayload, RootPayload> = defineFacet({
|
|
15
15
|
reducer: (inputs) => {
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
switch (inputs.length) {
|
|
17
|
+
case 0:
|
|
18
|
+
return { commands: {} }
|
|
19
|
+
case 1:
|
|
20
|
+
return { commands: inputs[0] }
|
|
21
|
+
default:
|
|
22
|
+
return { commands: Object.assign({}, ...inputs) as CommandCreators }
|
|
23
|
+
}
|
|
18
24
|
},
|
|
19
25
|
parent: rootFacet,
|
|
20
26
|
singleton: true,
|
package/src/facets/state.spec.ts
CHANGED
|
@@ -20,9 +20,9 @@ describe('state', () => {
|
|
|
20
20
|
const doc2: NodeJSON = { type: 'doc', content: [{ type: 'paragraph', content: [{ type: 'text', text: 'highest priority' }] }] }
|
|
21
21
|
const doc3: NodeJSON = { type: 'doc', content: [{ type: 'paragraph', content: [{ type: 'text', text: 'lowest priority' }] }] }
|
|
22
22
|
|
|
23
|
-
const extension1 = defineDefaultState({
|
|
24
|
-
const extension2 = withPriority(defineDefaultState({
|
|
25
|
-
const extension3 = withPriority(defineDefaultState({
|
|
23
|
+
const extension1 = defineDefaultState({ defaultContent: doc1 }) // default priority
|
|
24
|
+
const extension2 = withPriority(defineDefaultState({ defaultContent: doc2 }), Priority.highest)
|
|
25
|
+
const extension3 = withPriority(defineDefaultState({ defaultContent: doc3 }), Priority.lowest)
|
|
26
26
|
|
|
27
27
|
const combinedExtension = union(defineTestExtension(), extension1, extension2, extension3)
|
|
28
28
|
const { editor } = setupTestFromExtension(combinedExtension)
|
|
@@ -38,9 +38,9 @@ describe('state', () => {
|
|
|
38
38
|
const doc2 = { type: 'doc', content: [{ type: 'paragraph', content: [{ type: 'text', text: 'second' }] }] }
|
|
39
39
|
const doc3 = { type: 'doc', content: [{ type: 'paragraph', content: [{ type: 'text', text: 'third' }] }] }
|
|
40
40
|
|
|
41
|
-
const extension1 = defineDefaultState({
|
|
42
|
-
const extension2 = defineDefaultState({
|
|
43
|
-
const extension3 = defineDefaultState({
|
|
41
|
+
const extension1 = defineDefaultState({ defaultContent: doc1 })
|
|
42
|
+
const extension2 = defineDefaultState({ defaultContent: doc2 })
|
|
43
|
+
const extension3 = defineDefaultState({ defaultContent: doc3 })
|
|
44
44
|
|
|
45
45
|
const combinedExtension = union(defineTestExtension(), extension1, extension2, extension3)
|
|
46
46
|
const { editor } = setupTestFromExtension(combinedExtension)
|
package/src/facets/state.ts
CHANGED
|
@@ -9,7 +9,6 @@ import type {
|
|
|
9
9
|
Selection,
|
|
10
10
|
} from '@prosekit/pm/state'
|
|
11
11
|
|
|
12
|
-
import { toReversed } from '../utils/array'
|
|
13
12
|
import { assert } from '../utils/assert'
|
|
14
13
|
|
|
15
14
|
import {
|
|
@@ -37,7 +36,7 @@ export const stateFacet: Facet<StatePayload, RootPayload> = defineFacet({
|
|
|
37
36
|
|
|
38
37
|
// An array of state payloads from higher to lower priority. This matches the
|
|
39
38
|
// order of plugins required by ProseMirror.
|
|
40
|
-
const reversedCallbacks =
|
|
39
|
+
const reversedCallbacks = [...callbacks].reverse()
|
|
41
40
|
|
|
42
41
|
for (const callback of reversedCallbacks) {
|
|
43
42
|
const config = callback(ctx)
|
package/src/index.ts
CHANGED
|
@@ -22,6 +22,8 @@ export {
|
|
|
22
22
|
removeNode,
|
|
23
23
|
type RemoveNodeOptions,
|
|
24
24
|
} from './commands/remove-node'
|
|
25
|
+
export { selectAll } from './commands/select-all'
|
|
26
|
+
export { selectBlock } from './commands/select-block'
|
|
25
27
|
export {
|
|
26
28
|
setBlockType,
|
|
27
29
|
type SetBlockTypeOptions,
|
|
@@ -56,9 +58,7 @@ export {
|
|
|
56
58
|
} from './commands/wrap'
|
|
57
59
|
export type {
|
|
58
60
|
MarkAction,
|
|
59
|
-
MarkBuilder,
|
|
60
61
|
NodeAction,
|
|
61
|
-
NodeBuilder,
|
|
62
62
|
NodeChild,
|
|
63
63
|
} from './editor/action'
|
|
64
64
|
export {
|
|
@@ -85,10 +85,6 @@ export {
|
|
|
85
85
|
defineDefaultState,
|
|
86
86
|
type DefaultStateOptions,
|
|
87
87
|
} from './extensions/default-state'
|
|
88
|
-
export {
|
|
89
|
-
defineDoc,
|
|
90
|
-
type DocExtension,
|
|
91
|
-
} from './extensions/doc'
|
|
92
88
|
export {
|
|
93
89
|
defineDocChangeHandler,
|
|
94
90
|
type DocChangeHandler,
|
|
@@ -151,6 +147,7 @@ export {
|
|
|
151
147
|
export {
|
|
152
148
|
defineBaseKeymap,
|
|
153
149
|
type BaseKeymapExtension,
|
|
150
|
+
type BaseKeymapOptions,
|
|
154
151
|
} from './extensions/keymap-base'
|
|
155
152
|
export {
|
|
156
153
|
defineMarkAttr,
|
|
@@ -184,19 +181,11 @@ export {
|
|
|
184
181
|
type NodeViewComponentOptions,
|
|
185
182
|
type NodeViewFactoryOptions,
|
|
186
183
|
} from './extensions/node-view-effect'
|
|
187
|
-
export {
|
|
188
|
-
defineParagraph,
|
|
189
|
-
type ParagraphExtension,
|
|
190
|
-
} from './extensions/paragraph'
|
|
191
184
|
export {
|
|
192
185
|
definePlugin,
|
|
193
186
|
pluginFacet,
|
|
194
187
|
type PluginPayload,
|
|
195
188
|
} from './extensions/plugin'
|
|
196
|
-
export {
|
|
197
|
-
defineText,
|
|
198
|
-
type TextExtension,
|
|
199
|
-
} from './extensions/text'
|
|
200
189
|
export {
|
|
201
190
|
defineFacet,
|
|
202
191
|
type Facet,
|
|
@@ -207,12 +196,10 @@ export type {
|
|
|
207
196
|
AnyAttrs,
|
|
208
197
|
AttrSpec,
|
|
209
198
|
} from './types/attrs'
|
|
210
|
-
export type { BaseNodeViewOptions } from './types/base-node-view-options'
|
|
211
199
|
export type {
|
|
212
200
|
Extension,
|
|
213
201
|
ExtensionTyping,
|
|
214
202
|
ExtractCommandActions,
|
|
215
|
-
ExtractCommandAppliers,
|
|
216
203
|
ExtractCommandCreators,
|
|
217
204
|
ExtractCommands,
|
|
218
205
|
ExtractMarkActions,
|
|
@@ -222,7 +209,6 @@ export type {
|
|
|
222
209
|
ExtractTyping,
|
|
223
210
|
PlainExtension,
|
|
224
211
|
Union,
|
|
225
|
-
UnionExtension,
|
|
226
212
|
} from './types/extension'
|
|
227
213
|
export type {
|
|
228
214
|
CommandAction,
|
|
@@ -249,11 +235,6 @@ export type { SimplifyUnion } from './types/simplify-union'
|
|
|
249
235
|
export { assert } from './utils/assert'
|
|
250
236
|
export { canUseRegexLookbehind } from './utils/can-use-regex-lookbehind'
|
|
251
237
|
export { clsx } from './utils/clsx'
|
|
252
|
-
export { collectChildren } from './utils/collect-children'
|
|
253
|
-
export {
|
|
254
|
-
collectNodes,
|
|
255
|
-
type NodeContent,
|
|
256
|
-
} from './utils/collect-nodes'
|
|
257
238
|
export { containsInlineNode } from './utils/contains-inline-node'
|
|
258
239
|
export { defaultBlockAt } from './utils/default-block-at'
|
|
259
240
|
export { isApple } from './utils/env'
|
|
@@ -262,7 +243,6 @@ export {
|
|
|
262
243
|
type FindParentNodeResult,
|
|
263
244
|
} from './utils/find-parent-node'
|
|
264
245
|
export { findParentNodeOfType } from './utils/find-parent-node-of-type'
|
|
265
|
-
export { getId as _getId } from './utils/get-id'
|
|
266
246
|
export { getMarkType } from './utils/get-mark-type'
|
|
267
247
|
export { getNodeType } from './utils/get-node-type'
|
|
268
248
|
export { isAtBlockStart } from './utils/is-at-block-start'
|
|
@@ -19,13 +19,6 @@ export interface CommandAction<Args extends any[] = any[]> {
|
|
|
19
19
|
* can be executed, otherwise `false`.
|
|
20
20
|
*/
|
|
21
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
22
|
}
|
|
30
23
|
|
|
31
24
|
export type CommandCreator<Args extends any[] = any[]> = (
|
package/src/types/extension.ts
CHANGED
|
@@ -142,11 +142,6 @@ export type ExtractMarkActions<E extends Extension> = ToMarkAction<
|
|
|
142
142
|
ExtractMarks<E>
|
|
143
143
|
>
|
|
144
144
|
|
|
145
|
-
/**
|
|
146
|
-
* @deprecated Use `ExtractCommandActions` instead.
|
|
147
|
-
*/
|
|
148
|
-
export type ExtractCommandAppliers<E extends Extension> = ExtractCommandActions<E>
|
|
149
|
-
|
|
150
145
|
/**
|
|
151
146
|
* @internal
|
|
152
147
|
*/
|
|
@@ -155,14 +150,3 @@ export type Union<E extends readonly Extension[]> = Extension<{
|
|
|
155
150
|
Marks: ExtractMarks<E[number]>
|
|
156
151
|
Commands: ExtractCommands<E[number]>
|
|
157
152
|
}>
|
|
158
|
-
|
|
159
|
-
/**
|
|
160
|
-
* @deprecated Use `Union` instead.
|
|
161
|
-
* @internal
|
|
162
|
-
*/
|
|
163
|
-
export type UnionExtension<E extends Extension | readonly Extension[]> = E extends readonly Extension[] ? Extension<{
|
|
164
|
-
Nodes: ExtractNodes<E[number]>
|
|
165
|
-
Marks: ExtractMarks<E[number]>
|
|
166
|
-
Commands: ExtractCommands<E[number]>
|
|
167
|
-
}>
|
|
168
|
-
: E
|
|
@@ -3,10 +3,7 @@ import {
|
|
|
3
3
|
test,
|
|
4
4
|
} from 'vitest'
|
|
5
5
|
|
|
6
|
-
import {
|
|
7
|
-
groupBy,
|
|
8
|
-
groupEntries,
|
|
9
|
-
} from './array-grouping'
|
|
6
|
+
import { groupEntries } from './array-grouping'
|
|
10
7
|
|
|
11
8
|
test('groupEntries', () => {
|
|
12
9
|
expect(
|
|
@@ -20,10 +17,3 @@ test('groupEntries', () => {
|
|
|
20
17
|
b: [2],
|
|
21
18
|
})
|
|
22
19
|
})
|
|
23
|
-
|
|
24
|
-
test('groupBy', () => {
|
|
25
|
-
expect(groupBy([1, 2, 3, 4, 5], (n) => n % 2)).toEqual({
|
|
26
|
-
0: [2, 4],
|
|
27
|
-
1: [1, 3, 5],
|
|
28
|
-
})
|
|
29
|
-
})
|