@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,168 @@
|
|
|
1
|
+
import type { Schema } from '@prosekit/pm/model'
|
|
2
|
+
|
|
3
|
+
import type {
|
|
4
|
+
CommandTyping,
|
|
5
|
+
ToCommandAction,
|
|
6
|
+
ToCommandCreators,
|
|
7
|
+
} from './extension-command'
|
|
8
|
+
import type {
|
|
9
|
+
MarkTyping,
|
|
10
|
+
ToMarkAction,
|
|
11
|
+
} from './extension-mark'
|
|
12
|
+
import type {
|
|
13
|
+
NodeTyping,
|
|
14
|
+
ToNodeAction,
|
|
15
|
+
} from './extension-node'
|
|
16
|
+
import type { PickStringLiteral } from './pick-string-literal'
|
|
17
|
+
import type { PickSubType } from './pick-sub-type'
|
|
18
|
+
import type { Priority } from './priority'
|
|
19
|
+
import type { SimplifyDeeper } from './simplify-deeper'
|
|
20
|
+
import type { SimplifyUnion } from './simplify-union'
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* @internal
|
|
24
|
+
*/
|
|
25
|
+
export interface ExtensionTyping<
|
|
26
|
+
N extends NodeTyping = never,
|
|
27
|
+
M extends MarkTyping = never,
|
|
28
|
+
C extends CommandTyping = never,
|
|
29
|
+
> {
|
|
30
|
+
Nodes?: N
|
|
31
|
+
Marks?: M
|
|
32
|
+
Commands?: C
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* @public
|
|
37
|
+
*/
|
|
38
|
+
export interface Extension<
|
|
39
|
+
T extends ExtensionTyping<any, any, any> = ExtensionTyping<any, any, any>,
|
|
40
|
+
> {
|
|
41
|
+
extension: Extension | Extension[]
|
|
42
|
+
priority?: Priority
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* @public
|
|
46
|
+
*
|
|
47
|
+
* The schema that this extension represents.
|
|
48
|
+
*/
|
|
49
|
+
schema: Schema | null
|
|
50
|
+
|
|
51
|
+
/** @internal */
|
|
52
|
+
_type?: T
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* @internal
|
|
57
|
+
*/
|
|
58
|
+
export type ExtractTyping<E extends Extension> = E extends Extension<ExtensionTyping<infer N, infer M, infer C>> ? ExtensionTyping<
|
|
59
|
+
PickSubType<N, NodeTyping>,
|
|
60
|
+
PickSubType<M, MarkTyping>,
|
|
61
|
+
PickSubType<C, CommandTyping>
|
|
62
|
+
>
|
|
63
|
+
: never
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* An extension that does not define any nodes, marks, or commands.
|
|
67
|
+
*
|
|
68
|
+
* @internal
|
|
69
|
+
*/
|
|
70
|
+
export type PlainExtension = Extension<{
|
|
71
|
+
Nodes: never
|
|
72
|
+
Marks: never
|
|
73
|
+
Commands: never
|
|
74
|
+
}>
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* @public
|
|
78
|
+
*/
|
|
79
|
+
export type ExtractNodes<E extends Extension> = SimplifyDeeper<
|
|
80
|
+
SimplifyUnion<ExtractTyping<E>['Nodes']>
|
|
81
|
+
>
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* @public
|
|
85
|
+
*/
|
|
86
|
+
export type ExtractNodeNames<E extends Extension> = PickStringLiteral<
|
|
87
|
+
keyof ExtractNodes<E>
|
|
88
|
+
>
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* @public
|
|
92
|
+
*/
|
|
93
|
+
export type ExtractMarks<E extends Extension> = SimplifyDeeper<
|
|
94
|
+
SimplifyUnion<ExtractTyping<E>['Marks']>
|
|
95
|
+
>
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* @public
|
|
99
|
+
*/
|
|
100
|
+
export type ExtractMarkNames<E extends Extension> = PickStringLiteral<
|
|
101
|
+
keyof ExtractMarks<E>
|
|
102
|
+
>
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* @internal
|
|
106
|
+
*/
|
|
107
|
+
export type ExtractCommands<E extends Extension> = SimplifyUnion<
|
|
108
|
+
ExtractTyping<E>['Commands']
|
|
109
|
+
>
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* @public
|
|
113
|
+
*/
|
|
114
|
+
export type ExtractCommandCreators<E extends Extension> = ToCommandCreators<
|
|
115
|
+
ExtractCommands<E>
|
|
116
|
+
>
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Extracts the {@link CommandAction}s from an extension type.
|
|
120
|
+
*
|
|
121
|
+
* @public
|
|
122
|
+
*/
|
|
123
|
+
export type ExtractCommandActions<E extends Extension> = ToCommandAction<
|
|
124
|
+
ExtractCommands<E>
|
|
125
|
+
>
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Extracts the {@link NodeAction}s from an extension type.
|
|
129
|
+
*
|
|
130
|
+
* @public
|
|
131
|
+
*/
|
|
132
|
+
export type ExtractNodeActions<E extends Extension> = ToNodeAction<
|
|
133
|
+
ExtractNodes<E>
|
|
134
|
+
>
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Extracts the {@link MarkAction}s from an extension type.
|
|
138
|
+
*
|
|
139
|
+
* @public
|
|
140
|
+
*/
|
|
141
|
+
export type ExtractMarkActions<E extends Extension> = ToMarkAction<
|
|
142
|
+
ExtractMarks<E>
|
|
143
|
+
>
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* @deprecated Use `ExtractCommandActions` instead.
|
|
147
|
+
*/
|
|
148
|
+
export type ExtractCommandAppliers<E extends Extension> = ExtractCommandActions<E>
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* @internal
|
|
152
|
+
*/
|
|
153
|
+
export type Union<E extends readonly Extension[]> = Extension<{
|
|
154
|
+
Nodes: ExtractNodes<E[number]>
|
|
155
|
+
Marks: ExtractMarks<E[number]>
|
|
156
|
+
Commands: ExtractCommands<E[number]>
|
|
157
|
+
}>
|
|
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
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A JSON representation of the prosemirror node.
|
|
3
|
+
*
|
|
4
|
+
* @public
|
|
5
|
+
*/
|
|
6
|
+
export interface NodeJSON {
|
|
7
|
+
type: string
|
|
8
|
+
marks?: Array<{ type: string; attrs?: Record<string, any> }>
|
|
9
|
+
text?: string
|
|
10
|
+
content?: NodeJSON[]
|
|
11
|
+
attrs?: Record<string, any>
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* A JSON representation of the prosemirror selection.
|
|
16
|
+
*
|
|
17
|
+
* @public
|
|
18
|
+
*/
|
|
19
|
+
export interface SelectionJSON {
|
|
20
|
+
anchor: number
|
|
21
|
+
head: number
|
|
22
|
+
type: string
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* A JSON representation of the prosemirror state.
|
|
27
|
+
*
|
|
28
|
+
* @public
|
|
29
|
+
*/
|
|
30
|
+
export interface StateJSON {
|
|
31
|
+
/**
|
|
32
|
+
* The main `ProseMirror` doc.
|
|
33
|
+
*/
|
|
34
|
+
doc: NodeJSON
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* The current selection.
|
|
38
|
+
*/
|
|
39
|
+
selection: SelectionJSON
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* A JSON representation of the prosemirror step.
|
|
44
|
+
*
|
|
45
|
+
* @public
|
|
46
|
+
*/
|
|
47
|
+
export interface StepJSON {
|
|
48
|
+
/**
|
|
49
|
+
* The type of the step.
|
|
50
|
+
*/
|
|
51
|
+
stepType: string
|
|
52
|
+
|
|
53
|
+
[x: string]: unknown
|
|
54
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @internal
|
|
3
|
+
*
|
|
4
|
+
* @example
|
|
5
|
+
*
|
|
6
|
+
* ```
|
|
7
|
+
* type MyObject = { a: 1; b: 'B' }
|
|
8
|
+
* type MyEntries = ObjectEntries<MyObject>
|
|
9
|
+
* // ^ ["a", 1] | ["b", "B"]
|
|
10
|
+
*/
|
|
11
|
+
export type ObjectEntries<T extends Record<string, any>> = {
|
|
12
|
+
[K in keyof T]: [K, T[K]]
|
|
13
|
+
}[keyof T]
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { test } from 'vitest'
|
|
2
|
+
|
|
3
|
+
import { assertTypeEqual } from './assert-type-equal'
|
|
4
|
+
import type { PickStringLiteral } from './pick-string-literal'
|
|
5
|
+
|
|
6
|
+
test('PickStringLiteral', () => {
|
|
7
|
+
assertTypeEqual<PickStringLiteral<'foo'>, 'foo'>(true)
|
|
8
|
+
assertTypeEqual<PickStringLiteral<'foo' | 'bar'>, 'foo' | 'bar'>(true)
|
|
9
|
+
assertTypeEqual<PickStringLiteral<string>, never>(true)
|
|
10
|
+
})
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { test } from 'vitest'
|
|
2
|
+
|
|
3
|
+
import { assertTypeEqual } from './assert-type-equal'
|
|
4
|
+
import type { PickSubType } from './pick-sub-type'
|
|
5
|
+
|
|
6
|
+
test('PickSubType', () => {
|
|
7
|
+
assertTypeEqual<PickSubType<'abc', string>, 'abc'>(true)
|
|
8
|
+
assertTypeEqual<PickSubType<'abc' | 'def', string>, 'abc' | 'def'>(true)
|
|
9
|
+
assertTypeEqual<PickSubType<123, string>, never>(true)
|
|
10
|
+
assertTypeEqual<PickSubType<string, string>, never>(true)
|
|
11
|
+
|
|
12
|
+
assertTypeEqual<PickSubType<{ foo: 1 }, Record<string, number>>, { foo: 1 }>(
|
|
13
|
+
true,
|
|
14
|
+
)
|
|
15
|
+
assertTypeEqual<PickSubType<{ foo: 1 }, Record<string, string>>, never>(true)
|
|
16
|
+
assertTypeEqual<
|
|
17
|
+
PickSubType<Record<string, number>, Record<string, string>>,
|
|
18
|
+
never
|
|
19
|
+
>(true)
|
|
20
|
+
})
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { Simplify } from 'type-fest'
|
|
2
|
+
import { test } from 'vitest'
|
|
3
|
+
|
|
4
|
+
import { assertTypeEqual } from './assert-type-equal'
|
|
5
|
+
import type { SimplifyDeeper } from './simplify-deeper'
|
|
6
|
+
|
|
7
|
+
test('SimplifyDeeper', () => {
|
|
8
|
+
type T1 = {
|
|
9
|
+
nodeA: {
|
|
10
|
+
attr1: string
|
|
11
|
+
} & {
|
|
12
|
+
attr2: string
|
|
13
|
+
}
|
|
14
|
+
} & {
|
|
15
|
+
nodeB: {
|
|
16
|
+
attr3: string
|
|
17
|
+
} & {
|
|
18
|
+
attr4: string
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
interface T2 {
|
|
22
|
+
nodeA: {
|
|
23
|
+
attr1: string
|
|
24
|
+
attr2: string
|
|
25
|
+
}
|
|
26
|
+
nodeB: {
|
|
27
|
+
attr3: string
|
|
28
|
+
attr4: string
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
assertTypeEqual<T1, T1>(true)
|
|
33
|
+
assertTypeEqual<T1, T2>(false)
|
|
34
|
+
|
|
35
|
+
assertTypeEqual<T1, SimplifyDeeper<T1>>(false)
|
|
36
|
+
assertTypeEqual<T2, SimplifyDeeper<T1>>(true)
|
|
37
|
+
|
|
38
|
+
assertTypeEqual<T1, Simplify<T1>>(false)
|
|
39
|
+
assertTypeEqual<T2, Simplify<T1>>(false)
|
|
40
|
+
})
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { test } from 'vitest'
|
|
2
|
+
|
|
3
|
+
import { assertTypeEqual } from './assert-type-equal'
|
|
4
|
+
import type { SimplifyUnion } from './simplify-union'
|
|
5
|
+
|
|
6
|
+
test('SimplifyUnion', () => {
|
|
7
|
+
type T1 = { a: string } | { b: string }
|
|
8
|
+
|
|
9
|
+
interface T2 {
|
|
10
|
+
a: string
|
|
11
|
+
b: string
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
type T3 = SimplifyUnion<T1>
|
|
15
|
+
|
|
16
|
+
assertTypeEqual<T1, T1>(true)
|
|
17
|
+
assertTypeEqual<T1, T2>(false)
|
|
18
|
+
|
|
19
|
+
assertTypeEqual<T1, T3>(false)
|
|
20
|
+
assertTypeEqual<T2, T3>(true)
|
|
21
|
+
})
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import {
|
|
2
|
+
expect,
|
|
3
|
+
test,
|
|
4
|
+
} from 'vitest'
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
groupBy,
|
|
8
|
+
groupEntries,
|
|
9
|
+
} from './array-grouping'
|
|
10
|
+
|
|
11
|
+
test('groupEntries', () => {
|
|
12
|
+
expect(
|
|
13
|
+
groupEntries([
|
|
14
|
+
['a', 1],
|
|
15
|
+
['b', 2],
|
|
16
|
+
['a', 3],
|
|
17
|
+
]),
|
|
18
|
+
).toEqual({
|
|
19
|
+
a: [1, 3],
|
|
20
|
+
b: [2],
|
|
21
|
+
})
|
|
22
|
+
})
|
|
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
|
+
})
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { ObjectEntries } from '../types/object-entries'
|
|
2
|
+
|
|
3
|
+
export function groupBy<K extends PropertyKey, T>(
|
|
4
|
+
items: Iterable<T>,
|
|
5
|
+
keySelector: (item: T) => K,
|
|
6
|
+
): Partial<Record<K, T[]>> {
|
|
7
|
+
const result: Partial<Record<K, T[]>> = {}
|
|
8
|
+
for (const item of items) {
|
|
9
|
+
const key = keySelector(item)
|
|
10
|
+
const values = (result[key] ||= [])
|
|
11
|
+
values.push(item)
|
|
12
|
+
}
|
|
13
|
+
return result
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function groupEntries<T extends Record<string, any>>(
|
|
17
|
+
entries: ObjectEntries<T>[],
|
|
18
|
+
): { [K in keyof T]?: T[K][] } {
|
|
19
|
+
const result: { [K in keyof T]?: T[K][] } = {}
|
|
20
|
+
for (const [key, value] of entries) {
|
|
21
|
+
const values = (result[key] ||= [])
|
|
22
|
+
values.push(value)
|
|
23
|
+
}
|
|
24
|
+
return result
|
|
25
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export function uniqPush<T>(prev: readonly T[], next: readonly T[]): T[] {
|
|
2
|
+
const result = [...prev]
|
|
3
|
+
|
|
4
|
+
for (const item of next) {
|
|
5
|
+
if (!result.includes(item)) {
|
|
6
|
+
result.push(item)
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
return result
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @internal
|
|
14
|
+
*/
|
|
15
|
+
export function arraySubtract<T>(a: T[], b: T[]): T[] {
|
|
16
|
+
return a.filter((x) => !b.includes(x))
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function toReversed<T>(arr: T[]): T[] {
|
|
20
|
+
return arr.toReversed?.() ?? [...arr].reverse()
|
|
21
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
Attrs,
|
|
3
|
+
Mark,
|
|
4
|
+
ProseMirrorNode,
|
|
5
|
+
} from '@prosekit/pm/model'
|
|
6
|
+
|
|
7
|
+
export function attrsMatch(
|
|
8
|
+
nodeOrMark: ProseMirrorNode | Mark,
|
|
9
|
+
attrs: Attrs,
|
|
10
|
+
): boolean {
|
|
11
|
+
const currentAttrs = nodeOrMark.attrs
|
|
12
|
+
|
|
13
|
+
for (const [key, value] of Object.entries(attrs)) {
|
|
14
|
+
if (currentAttrs[key] !== value) {
|
|
15
|
+
return false
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
return true
|
|
20
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { once } from '@ocavue/utils'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Checks if the browser supports [regex lookbehind assertion](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Regular_expressions/Lookbehind_assertion).
|
|
5
|
+
*/
|
|
6
|
+
export const canUseRegexLookbehind: () => boolean = once(() => {
|
|
7
|
+
try {
|
|
8
|
+
return 'ab'.replace(new RegExp('(?<=a)b', 'g'), 'c') === 'ac'
|
|
9
|
+
} catch {
|
|
10
|
+
return false
|
|
11
|
+
}
|
|
12
|
+
})
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import {
|
|
2
|
+
expect,
|
|
3
|
+
test,
|
|
4
|
+
} from 'vitest'
|
|
5
|
+
|
|
6
|
+
import { clsx } from './clsx'
|
|
7
|
+
|
|
8
|
+
test('joins class names', () => {
|
|
9
|
+
expect(clsx('foo', 'bar')).toBe('foo bar')
|
|
10
|
+
})
|
|
11
|
+
|
|
12
|
+
test('filters falsy values', () => {
|
|
13
|
+
expect(clsx('foo', false, null, undefined, 'baz')).toBe('foo baz')
|
|
14
|
+
})
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import clsxLite from 'clsx/lite'
|
|
2
|
+
|
|
3
|
+
// This type declaration can be removed if https://github.com/lukeed/clsx/pull/110 gets merged and released
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* A utility for constructing `className` strings conditionally.
|
|
7
|
+
*
|
|
8
|
+
* It is a re-export of [clsx/lite](https://www.npmjs.com/package/clsx) with stricter types.
|
|
9
|
+
*
|
|
10
|
+
* @public
|
|
11
|
+
*/
|
|
12
|
+
export const clsx: (
|
|
13
|
+
...args: Array<string | boolean | null | undefined>
|
|
14
|
+
) => string = clsxLite
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
Fragment,
|
|
3
|
+
ProseMirrorNode,
|
|
4
|
+
} from '@prosekit/pm/model'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Collects all children of a node or a fragment, and returns them as an array.
|
|
8
|
+
*
|
|
9
|
+
* @deprecated Use `node.children` or `fragment.content` instead.
|
|
10
|
+
*
|
|
11
|
+
* @hidden
|
|
12
|
+
*/
|
|
13
|
+
export function collectChildren(
|
|
14
|
+
parent: ProseMirrorNode | Fragment,
|
|
15
|
+
): ProseMirrorNode[] {
|
|
16
|
+
const children: ProseMirrorNode[] = []
|
|
17
|
+
for (let i = 0; i < parent.childCount; i++) {
|
|
18
|
+
children.push(parent.child(i))
|
|
19
|
+
}
|
|
20
|
+
return children
|
|
21
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ProseMirrorFragment,
|
|
3
|
+
ProseMirrorNode,
|
|
4
|
+
} from '@prosekit/pm/model'
|
|
5
|
+
|
|
6
|
+
import { ProseKitError } from '../error'
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @hidden
|
|
10
|
+
*
|
|
11
|
+
* @deprecated
|
|
12
|
+
*/
|
|
13
|
+
export type NodeContent = ProseMirrorNode | ProseMirrorFragment | NodeContent[]
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Collects all nodes from a given content.
|
|
17
|
+
*
|
|
18
|
+
* @deprecated Use `collectChildren` instead.
|
|
19
|
+
*
|
|
20
|
+
* @hidden
|
|
21
|
+
*/
|
|
22
|
+
export function collectNodes(content: NodeContent): ProseMirrorNode[] {
|
|
23
|
+
if (Array.isArray(content)) {
|
|
24
|
+
return content.flatMap(collectNodes)
|
|
25
|
+
}
|
|
26
|
+
if (content instanceof ProseMirrorNode) {
|
|
27
|
+
return [content]
|
|
28
|
+
}
|
|
29
|
+
if (content instanceof ProseMirrorFragment) {
|
|
30
|
+
const nodes: ProseMirrorNode[] = []
|
|
31
|
+
for (let i = 0; i < content.childCount; i++) {
|
|
32
|
+
nodes.push(content.child(i))
|
|
33
|
+
}
|
|
34
|
+
return nodes
|
|
35
|
+
}
|
|
36
|
+
throw new ProseKitError(`Invalid node content: ${typeof content}`)
|
|
37
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import {
|
|
2
|
+
expect,
|
|
3
|
+
test,
|
|
4
|
+
vi,
|
|
5
|
+
} from 'vitest'
|
|
6
|
+
|
|
7
|
+
import { combineEventHandlers } from './combine-event-handlers'
|
|
8
|
+
|
|
9
|
+
test('runs handlers in reverse order and stops on true', () => {
|
|
10
|
+
const handler1 = vi.fn(() => false)
|
|
11
|
+
const handler2 = vi.fn(() => true)
|
|
12
|
+
const handler3 = vi.fn(() => false)
|
|
13
|
+
const [setHandlers, run] = combineEventHandlers<() => boolean>()
|
|
14
|
+
setHandlers([handler1, handler2, handler3])
|
|
15
|
+
expect(run()).toBe(true)
|
|
16
|
+
expect(handler3).toHaveBeenCalled()
|
|
17
|
+
expect(handler2).toHaveBeenCalled()
|
|
18
|
+
expect(handler1).not.toHaveBeenCalled()
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
test('returns false when all handlers return false', () => {
|
|
22
|
+
const handler1 = vi.fn(() => false)
|
|
23
|
+
const handler2 = vi.fn(() => false)
|
|
24
|
+
const [setHandlers, run] = combineEventHandlers<() => boolean>()
|
|
25
|
+
setHandlers([handler1, handler2])
|
|
26
|
+
expect(run()).toBe(false)
|
|
27
|
+
})
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { toReversed } from './array'
|
|
2
|
+
|
|
3
|
+
export function combineEventHandlers<
|
|
4
|
+
Handler extends (...args: any[]) => boolean | void,
|
|
5
|
+
Args extends Parameters<Handler> = Parameters<Handler>,
|
|
6
|
+
>(): [
|
|
7
|
+
setHandlers: (eventHandlers: Handler[]) => void,
|
|
8
|
+
combinedEventHandler: (...args: Args) => boolean,
|
|
9
|
+
] {
|
|
10
|
+
let handlers: Handler[] = []
|
|
11
|
+
|
|
12
|
+
function setHandlers(eventHandlers: Handler[]): void {
|
|
13
|
+
// The handlers at the end have a higher priority.
|
|
14
|
+
handlers = toReversed(eventHandlers)
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function combinedEventHandler(...args: Args): boolean {
|
|
18
|
+
for (const handler of handlers) {
|
|
19
|
+
if (handler(...args)) {
|
|
20
|
+
return true
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return false
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return [setHandlers, combinedEventHandler] as const
|
|
27
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { ProseMirrorNode } from '@prosekit/pm/model'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @internal
|
|
5
|
+
*/
|
|
6
|
+
export function containsInlineNode(
|
|
7
|
+
doc: ProseMirrorNode,
|
|
8
|
+
from: number,
|
|
9
|
+
to: number,
|
|
10
|
+
): boolean {
|
|
11
|
+
let found = false
|
|
12
|
+
doc.nodesBetween(from, to, (node) => {
|
|
13
|
+
if (found) return false
|
|
14
|
+
if (node.isInline) found = true
|
|
15
|
+
})
|
|
16
|
+
return found
|
|
17
|
+
}
|