@prosekit/extensions 0.14.0 → 0.14.1
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/{drop-indicator-B_oMfeVP.js → drop-indicator-DJq8pF92.js} +1 -1
- package/dist/{drop-indicator-B_oMfeVP.js.map → drop-indicator-DJq8pF92.js.map} +1 -1
- package/dist/{file-iLVR0eM0.js → file-upload-I9m1EJAM.js} +1 -1
- package/dist/file-upload-I9m1EJAM.js.map +1 -0
- package/dist/{index-cp1u4e0e.d.ts → file-upload-dr3IXUty.d.ts} +1 -1
- package/dist/file-upload-dr3IXUty.d.ts.map +1 -0
- package/dist/{paste-rule-BaDghcaU.js → mark-paste-rule-n_2Ehmb5.js} +1 -1
- package/dist/mark-paste-rule-n_2Ehmb5.js.map +1 -0
- package/dist/{mark-rule-CYe8zk4q.js → mark-rule-CUnXwBuy.js} +1 -1
- package/dist/{mark-rule-CYe8zk4q.js.map → mark-rule-CUnXwBuy.js.map} +1 -1
- package/dist/prosekit-extensions-blockquote.js +1 -1
- package/dist/prosekit-extensions-bold.js +1 -1
- package/dist/prosekit-extensions-code-block.d.ts +1 -1
- package/dist/prosekit-extensions-code-block.js +2 -2
- package/dist/prosekit-extensions-code.js +1 -1
- package/dist/prosekit-extensions-drop-indicator.js +1 -1
- package/dist/prosekit-extensions-enter-rule.d.ts +6 -78
- package/dist/prosekit-extensions-enter-rule.d.ts.map +1 -1
- package/dist/prosekit-extensions-enter-rule.js +37 -2
- package/dist/prosekit-extensions-enter-rule.js.map +1 -0
- package/dist/prosekit-extensions-file.d.ts +2 -2
- package/dist/prosekit-extensions-file.js +1 -1
- package/dist/prosekit-extensions-heading.js +1 -1
- package/dist/prosekit-extensions-horizontal-rule.js +1 -1
- package/dist/prosekit-extensions-image.d.ts +2 -1
- package/dist/prosekit-extensions-image.d.ts.map +1 -1
- package/dist/prosekit-extensions-image.js +1 -1
- package/dist/prosekit-extensions-input-rule.js +89 -2
- package/dist/prosekit-extensions-input-rule.js.map +1 -0
- package/dist/prosekit-extensions-italic.js +1 -1
- package/dist/prosekit-extensions-link.js +4 -4
- package/dist/prosekit-extensions-list.js +2 -2
- package/dist/prosekit-extensions-mark-rule.js +1 -1
- package/dist/prosekit-extensions-math.d.ts +154 -0
- package/dist/prosekit-extensions-math.d.ts.map +1 -0
- package/dist/prosekit-extensions-math.js +104 -0
- package/dist/prosekit-extensions-math.js.map +1 -0
- package/dist/prosekit-extensions-paste-rule.js +1 -1
- package/dist/prosekit-extensions-placeholder.js +1 -1
- package/dist/prosekit-extensions-strike.js +1 -1
- package/dist/prosekit-extensions-table.js +1 -1
- package/dist/prosekit-extensions-yjs.d.ts.map +1 -1
- package/dist/shiki-highlighter-chunk.d.ts +19 -2
- package/dist/shiki-highlighter-chunk.d.ts.map +1 -0
- package/dist/{table-4oHfV-Ql.js → table-UJVYsrB7.js} +2 -2
- package/dist/{table-4oHfV-Ql.js.map → table-UJVYsrB7.js.map} +1 -1
- package/package.json +19 -8
- package/src/enter-rule/index.ts +18 -191
- package/src/math/index.ts +22 -0
- package/src/math/math-block.ts +89 -0
- package/src/math/math-inline.ts +89 -0
- package/src/math/math-plugin.ts +8 -0
- package/src/math/math.ts +39 -0
- package/src/testing/index.ts +3 -0
- package/src/testing/katex.ts +9 -0
- package/src/yjs/yjs-types.ts +0 -2
- package/dist/enter-rule-D-p4ykfv.js +0 -96
- package/dist/enter-rule-D-p4ykfv.js.map +0 -1
- package/dist/file-iLVR0eM0.js.map +0 -1
- package/dist/index-cp1u4e0e.d.ts.map +0 -1
- package/dist/input-rule-COGr_GBb.js +0 -90
- package/dist/input-rule-COGr_GBb.js.map +0 -1
- package/dist/paste-rule-BaDghcaU.js.map +0 -1
- package/dist/shiki-highlighter-chunk-DNNm2Vow.d.ts +0 -19
- package/dist/shiki-highlighter-chunk-DNNm2Vow.d.ts.map +0 -1
package/src/enter-rule/index.ts
CHANGED
|
@@ -1,104 +1,28 @@
|
|
|
1
|
+
import { defineFacet, defineFacetPayload, pluginFacet, type PlainExtension, type PluginPayload } from '@prosekit/core'
|
|
1
2
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
type PlainExtension,
|
|
10
|
-
type PluginPayload,
|
|
11
|
-
} from '@prosekit/core'
|
|
12
|
-
import { keydownHandler } from '@prosekit/pm/keymap'
|
|
13
|
-
import type { Attrs, NodeType } from '@prosekit/pm/model'
|
|
14
|
-
import { PluginKey, ProseMirrorPlugin, type Command, type EditorState, type Transaction } from '@prosekit/pm/state'
|
|
15
|
-
import type { EditorView } from '@prosekit/pm/view'
|
|
3
|
+
createEnterRulePlugin,
|
|
4
|
+
createTextBlockEnterRule,
|
|
5
|
+
type EnterRule,
|
|
6
|
+
type EnterRuleHandler,
|
|
7
|
+
type EnterRuleHandlerOptions,
|
|
8
|
+
type TextBlockEnterRuleOptions as _TextBlockEnterRuleOptions,
|
|
9
|
+
} from 'prosemirror-enter-rules'
|
|
16
10
|
|
|
17
|
-
|
|
18
|
-
* @public
|
|
19
|
-
*
|
|
20
|
-
* Options for {@link EnterRuleHandler}.
|
|
21
|
-
*/
|
|
22
|
-
export interface EnterRuleHandlerOptions {
|
|
23
|
-
/**
|
|
24
|
-
* The current editor state.
|
|
25
|
-
*/
|
|
26
|
-
state: EditorState
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* The start position of the matched text.
|
|
30
|
-
*/
|
|
31
|
-
from: number
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* The end position of the matched text.
|
|
35
|
-
*/
|
|
36
|
-
to: number
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* The matched result from the regular expression.
|
|
40
|
-
*/
|
|
41
|
-
match: RegExpExecArray
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* @public
|
|
46
|
-
*/
|
|
47
|
-
export type EnterRuleHandler = (options: EnterRuleHandlerOptions) => Transaction | null
|
|
11
|
+
export type { EnterRuleHandler, EnterRuleHandlerOptions }
|
|
48
12
|
|
|
49
13
|
/**
|
|
50
14
|
* Options for {@link defineEnterRule}.
|
|
51
15
|
*
|
|
52
16
|
* @public
|
|
53
17
|
*/
|
|
54
|
-
export type EnterRuleOptions =
|
|
55
|
-
/**
|
|
56
|
-
* The regular expression to match against. It should end with `$`.
|
|
57
|
-
*/
|
|
58
|
-
regex: RegExp
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* A function to be called when an enter rule is triggered.
|
|
62
|
-
*/
|
|
63
|
-
handler: EnterRuleHandler
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* Whether to stop further handlers from being called if this rule is triggered.
|
|
67
|
-
*
|
|
68
|
-
* @default false
|
|
69
|
-
*/
|
|
70
|
-
stop?: boolean
|
|
71
|
-
}
|
|
18
|
+
export type EnterRuleOptions = EnterRule
|
|
72
19
|
|
|
73
20
|
/**
|
|
74
21
|
* Options for {@link defineTextBlockEnterRule}.
|
|
75
22
|
*
|
|
76
23
|
* @public
|
|
77
24
|
*/
|
|
78
|
-
export
|
|
79
|
-
/**
|
|
80
|
-
* The regular expression to match against. It should end with `$`.
|
|
81
|
-
*/
|
|
82
|
-
regex: RegExp
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
* The node type to replace the matched text with.
|
|
86
|
-
*/
|
|
87
|
-
type: string | NodeType
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* Attributes to set on the node. If a function is provided, it will be called
|
|
91
|
-
* with the matched result from the regular expression.
|
|
92
|
-
*/
|
|
93
|
-
attrs?: Attrs | null | ((match: RegExpMatchArray) => Attrs | null)
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* Whether to stop further handlers from being called if this rule is triggered.
|
|
97
|
-
*
|
|
98
|
-
* @default true
|
|
99
|
-
*/
|
|
100
|
-
stop?: boolean
|
|
101
|
-
}
|
|
25
|
+
export type TextBlockEnterRuleOptions = _TextBlockEnterRuleOptions
|
|
102
26
|
|
|
103
27
|
/**
|
|
104
28
|
* Defines an enter rule. An enter rule applies when the text directly in front of
|
|
@@ -109,13 +33,8 @@ export interface TextBlockEnterRuleOptions {
|
|
|
109
33
|
*
|
|
110
34
|
* @public
|
|
111
35
|
*/
|
|
112
|
-
export function defineEnterRule({
|
|
113
|
-
|
|
114
|
-
handler,
|
|
115
|
-
stop = false,
|
|
116
|
-
}: EnterRuleOptions): PlainExtension {
|
|
117
|
-
const rule: EnterRule = new EnterRule(regex, handler, stop)
|
|
118
|
-
return defineFacetPayload(enterRule, [rule]) as PlainExtension
|
|
36
|
+
export function defineEnterRule(options: EnterRuleOptions): PlainExtension {
|
|
37
|
+
return defineFacetPayload(enterRuleFacet, [options]) as PlainExtension
|
|
119
38
|
}
|
|
120
39
|
|
|
121
40
|
/**
|
|
@@ -127,106 +46,14 @@ export function defineEnterRule({
|
|
|
127
46
|
*
|
|
128
47
|
* @public
|
|
129
48
|
*/
|
|
130
|
-
export function defineTextBlockEnterRule({
|
|
131
|
-
|
|
132
|
-
type,
|
|
133
|
-
attrs,
|
|
134
|
-
stop = true,
|
|
135
|
-
}: TextBlockEnterRuleOptions): PlainExtension {
|
|
136
|
-
return defineEnterRule({
|
|
137
|
-
regex,
|
|
138
|
-
handler: ({ state, from, to, match }) => {
|
|
139
|
-
const nodeType = getNodeType(state.schema, type)
|
|
140
|
-
const $start = state.doc.resolve(from)
|
|
141
|
-
|
|
142
|
-
if (
|
|
143
|
-
!$start
|
|
144
|
-
.node(-1)
|
|
145
|
-
.canReplaceWith($start.index(-1), $start.indexAfter(-1), nodeType)
|
|
146
|
-
) {
|
|
147
|
-
return null
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
const nodeAttrs = maybeRun(attrs, match)
|
|
151
|
-
return state.tr
|
|
152
|
-
.delete(from, to)
|
|
153
|
-
.setBlockType(from, from, nodeType, nodeAttrs)
|
|
154
|
-
},
|
|
155
|
-
stop,
|
|
156
|
-
})
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
/**
|
|
160
|
-
* @internal
|
|
161
|
-
*/
|
|
162
|
-
class EnterRule {
|
|
163
|
-
constructor(
|
|
164
|
-
readonly regex: RegExp,
|
|
165
|
-
readonly handler: EnterRuleHandler,
|
|
166
|
-
readonly stop: boolean,
|
|
167
|
-
) {}
|
|
49
|
+
export function defineTextBlockEnterRule(options: TextBlockEnterRuleOptions): PlainExtension {
|
|
50
|
+
return defineEnterRule(createTextBlockEnterRule(options))
|
|
168
51
|
}
|
|
169
52
|
|
|
170
|
-
const
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
const command: Command = (state, dispatch, view) => {
|
|
175
|
-
if (!view) return false
|
|
176
|
-
return execRules(view, rules, dispatch)
|
|
177
|
-
}
|
|
178
|
-
const handler = keydownHandler({ Enter: command })
|
|
179
|
-
const plugin = new ProseMirrorPlugin({
|
|
180
|
-
key: new PluginKey('prosekit-enter-rule'),
|
|
181
|
-
props: { handleKeyDown: handler },
|
|
182
|
-
})
|
|
183
|
-
|
|
184
|
-
return function reducer(inputs) {
|
|
185
|
-
rules = inputs
|
|
186
|
-
return plugin
|
|
187
|
-
}
|
|
53
|
+
const enterRuleFacet = defineFacet<EnterRule, PluginPayload>({
|
|
54
|
+
reducer: (rules: EnterRule[]): PluginPayload => {
|
|
55
|
+
return createEnterRulePlugin({ rules })
|
|
188
56
|
},
|
|
189
57
|
|
|
190
58
|
parent: pluginFacet,
|
|
191
59
|
})
|
|
192
|
-
|
|
193
|
-
function execRules(
|
|
194
|
-
view: EditorView,
|
|
195
|
-
rules: readonly EnterRule[],
|
|
196
|
-
dispatch?: (tr: Transaction) => void,
|
|
197
|
-
): boolean {
|
|
198
|
-
if (view.composing) return false
|
|
199
|
-
const state = view.state
|
|
200
|
-
const selection = state.selection
|
|
201
|
-
if (!isTextSelection(selection)) return false
|
|
202
|
-
const $cursor = selection.$cursor
|
|
203
|
-
if (!$cursor || $cursor.parent.type.spec.code) return false
|
|
204
|
-
|
|
205
|
-
const textBefore = $cursor.parent.textBetween(
|
|
206
|
-
Math.max(0, $cursor.parentOffset - MAX_MATCH),
|
|
207
|
-
$cursor.parentOffset,
|
|
208
|
-
null,
|
|
209
|
-
OBJECT_REPLACEMENT_CHARACTER,
|
|
210
|
-
)
|
|
211
|
-
|
|
212
|
-
for (const rule of rules) {
|
|
213
|
-
rule.regex.lastIndex = 0
|
|
214
|
-
const match = rule.regex.exec(textBefore)
|
|
215
|
-
const tr = match
|
|
216
|
-
&& rule.handler({
|
|
217
|
-
state,
|
|
218
|
-
from: $cursor.pos - match[0].length,
|
|
219
|
-
to: $cursor.pos,
|
|
220
|
-
match,
|
|
221
|
-
})
|
|
222
|
-
if (!tr) continue
|
|
223
|
-
dispatch?.(tr)
|
|
224
|
-
|
|
225
|
-
if (rule.stop) {
|
|
226
|
-
return true
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
return false
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
const MAX_MATCH = 200
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export { defineMath, type MathExtension, type MathOptions } from './math'
|
|
2
|
+
export {
|
|
3
|
+
defineMathBlock,
|
|
4
|
+
defineMathBlockEnterRule,
|
|
5
|
+
defineMathBlockSpec,
|
|
6
|
+
defineMathBlockView,
|
|
7
|
+
type MathBlockExtension,
|
|
8
|
+
type MathBlockOptions,
|
|
9
|
+
type MathBlockSpecExtension,
|
|
10
|
+
type MathBlockViewOptions,
|
|
11
|
+
} from './math-block'
|
|
12
|
+
export {
|
|
13
|
+
defineMathInline,
|
|
14
|
+
defineMathInlineInputRule,
|
|
15
|
+
defineMathInlineSpec,
|
|
16
|
+
defineMathInlineView,
|
|
17
|
+
type MathInlineExtension,
|
|
18
|
+
type MathInlineOptions,
|
|
19
|
+
type MathInlineSpecExtension,
|
|
20
|
+
type MathInlineViewOptions,
|
|
21
|
+
} from './math-inline'
|
|
22
|
+
export { defineMathPlugin } from './math-plugin'
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { defineNodeSpec, defineNodeView, union, type Extension, type PlainExtension, type Union } from '@prosekit/core'
|
|
2
|
+
import type { Attrs } from '@prosekit/pm/model'
|
|
3
|
+
import { createMathBlockView, mathBlockEnterRule, mathBlockSpec, type RenderMathBlock } from 'prosemirror-math'
|
|
4
|
+
|
|
5
|
+
import { defineEnterRule } from '../enter-rule'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @internal
|
|
9
|
+
*/
|
|
10
|
+
export type MathBlockSpecExtension = Extension<{
|
|
11
|
+
Nodes: {
|
|
12
|
+
mathBlock: Attrs
|
|
13
|
+
}
|
|
14
|
+
}>
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* @internal
|
|
18
|
+
*/
|
|
19
|
+
export function defineMathBlockSpec(): MathBlockSpecExtension {
|
|
20
|
+
return defineNodeSpec<'mathBlock', Attrs>({
|
|
21
|
+
...mathBlockSpec,
|
|
22
|
+
name: 'mathBlock',
|
|
23
|
+
})
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Options for {@link defineMathBlockView}.
|
|
28
|
+
*
|
|
29
|
+
* @internal
|
|
30
|
+
*/
|
|
31
|
+
export interface MathBlockViewOptions {
|
|
32
|
+
/**
|
|
33
|
+
* The function to render the math block.
|
|
34
|
+
*/
|
|
35
|
+
render: RenderMathBlock
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Defines an extension that renders a math block using a custom node view.
|
|
40
|
+
*
|
|
41
|
+
* @param options
|
|
42
|
+
* @internal
|
|
43
|
+
*/
|
|
44
|
+
export function defineMathBlockView({ render }: MathBlockViewOptions): Extension {
|
|
45
|
+
return defineNodeView({
|
|
46
|
+
name: 'mathBlock',
|
|
47
|
+
constructor: (node, view, getPos, decorations) => {
|
|
48
|
+
return createMathBlockView(render, node, decorations)
|
|
49
|
+
},
|
|
50
|
+
})
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* @internal
|
|
55
|
+
*/
|
|
56
|
+
export function defineMathBlockEnterRule(): PlainExtension {
|
|
57
|
+
return defineEnterRule(mathBlockEnterRule)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Options for {@link defineMathBlock}.
|
|
62
|
+
*
|
|
63
|
+
* @internal
|
|
64
|
+
*/
|
|
65
|
+
export interface MathBlockOptions {
|
|
66
|
+
/**
|
|
67
|
+
* The function to render the math block.
|
|
68
|
+
*/
|
|
69
|
+
render: RenderMathBlock
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* @internal
|
|
74
|
+
*/
|
|
75
|
+
export type MathBlockExtension = Union<[MathBlockSpecExtension]>
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Defines node `mathBlock` and related functionalities.
|
|
79
|
+
*
|
|
80
|
+
* @param options
|
|
81
|
+
* @public
|
|
82
|
+
*/
|
|
83
|
+
export function defineMathBlock(options: MathBlockOptions): MathBlockExtension {
|
|
84
|
+
return union(
|
|
85
|
+
defineMathBlockSpec(),
|
|
86
|
+
defineMathBlockView(options),
|
|
87
|
+
defineMathBlockEnterRule(),
|
|
88
|
+
)
|
|
89
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { defineNodeSpec, defineNodeView, union, type Extension, type PlainExtension, type Union } from '@prosekit/core'
|
|
2
|
+
import type { Attrs } from '@prosekit/pm/model'
|
|
3
|
+
import { createMathInlineInputRule, createMathInlineView, mathInlineSpec, type RenderMathInline } from 'prosemirror-math'
|
|
4
|
+
|
|
5
|
+
import { defineInputRule } from '../input-rule'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @internal
|
|
9
|
+
*/
|
|
10
|
+
export type MathInlineSpecExtension = Extension<{
|
|
11
|
+
Nodes: {
|
|
12
|
+
mathInline: Attrs
|
|
13
|
+
}
|
|
14
|
+
}>
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* @internal
|
|
18
|
+
*/
|
|
19
|
+
export function defineMathInlineSpec(): MathInlineSpecExtension {
|
|
20
|
+
return defineNodeSpec<'mathInline', Attrs>({
|
|
21
|
+
...mathInlineSpec,
|
|
22
|
+
name: 'mathInline',
|
|
23
|
+
})
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Options for {@link defineMathInlineView}.
|
|
28
|
+
*
|
|
29
|
+
* @internal
|
|
30
|
+
*/
|
|
31
|
+
export interface MathInlineViewOptions {
|
|
32
|
+
/**
|
|
33
|
+
* The function to render the math inline.
|
|
34
|
+
*/
|
|
35
|
+
render: RenderMathInline
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Defines an extension that renders a math inline using a custom node view.
|
|
40
|
+
*
|
|
41
|
+
* @param options
|
|
42
|
+
* @internal
|
|
43
|
+
*/
|
|
44
|
+
export function defineMathInlineView({ render }: MathInlineViewOptions): Extension {
|
|
45
|
+
return defineNodeView({
|
|
46
|
+
name: 'mathInline',
|
|
47
|
+
constructor: (node, view, getPos, decorations) => {
|
|
48
|
+
return createMathInlineView(render, node, decorations)
|
|
49
|
+
},
|
|
50
|
+
})
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* @internal
|
|
55
|
+
*/
|
|
56
|
+
export function defineMathInlineInputRule(): PlainExtension {
|
|
57
|
+
return defineInputRule(createMathInlineInputRule('mathInline'))
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Options for {@link defineMathInline}.
|
|
62
|
+
*
|
|
63
|
+
* @internal
|
|
64
|
+
*/
|
|
65
|
+
export interface MathInlineOptions {
|
|
66
|
+
/**
|
|
67
|
+
* The function to render the math inline.
|
|
68
|
+
*/
|
|
69
|
+
render: RenderMathInline
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* @internal
|
|
74
|
+
*/
|
|
75
|
+
export type MathInlineExtension = Union<[MathInlineSpecExtension]>
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Defines node `mathInline` and related functionalities.
|
|
79
|
+
*
|
|
80
|
+
* @param options
|
|
81
|
+
* @public
|
|
82
|
+
*/
|
|
83
|
+
export function defineMathInline(options: MathInlineOptions): MathInlineExtension {
|
|
84
|
+
return union(
|
|
85
|
+
defineMathInlineSpec(),
|
|
86
|
+
defineMathInlineView(options),
|
|
87
|
+
defineMathInlineInputRule(),
|
|
88
|
+
)
|
|
89
|
+
}
|
package/src/math/math.ts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { union, type Union } from '@prosekit/core'
|
|
2
|
+
import type { RenderMathBlock, RenderMathInline } from 'prosemirror-math'
|
|
3
|
+
|
|
4
|
+
import { defineMathBlock, type MathBlockExtension } from './math-block'
|
|
5
|
+
import { defineMathInline, type MathInlineExtension } from './math-inline'
|
|
6
|
+
import { defineMathPlugin } from './math-plugin'
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @public
|
|
10
|
+
*/
|
|
11
|
+
export type MathExtension = Union<[MathInlineExtension, MathBlockExtension]>
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Options for {@link defineMath}.
|
|
15
|
+
*
|
|
16
|
+
* @public
|
|
17
|
+
*/
|
|
18
|
+
export interface MathOptions {
|
|
19
|
+
/**
|
|
20
|
+
* The function to render the math block.
|
|
21
|
+
*/
|
|
22
|
+
renderMathBlock: RenderMathBlock
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* The function to render the math inline.
|
|
26
|
+
*/
|
|
27
|
+
renderMathInline: RenderMathInline
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* @public
|
|
32
|
+
*/
|
|
33
|
+
export function defineMath(options: MathOptions): MathExtension {
|
|
34
|
+
return union(
|
|
35
|
+
defineMathBlock({ render: options.renderMathBlock }),
|
|
36
|
+
defineMathInline({ render: options.renderMathInline }),
|
|
37
|
+
defineMathPlugin(),
|
|
38
|
+
)
|
|
39
|
+
}
|
package/src/testing/index.ts
CHANGED
|
@@ -26,6 +26,7 @@ import { defineImage } from '../image'
|
|
|
26
26
|
import { defineItalic } from '../italic'
|
|
27
27
|
import { defineLink } from '../link'
|
|
28
28
|
import { defineList, type ListAttrs } from '../list'
|
|
29
|
+
import { defineMath } from '../math'
|
|
29
30
|
import { defineParagraph } from '../paragraph'
|
|
30
31
|
import { defineStrike } from '../strike'
|
|
31
32
|
import { defineTable } from '../table'
|
|
@@ -35,6 +36,7 @@ import { defineTextColor } from '../text-color'
|
|
|
35
36
|
import { defineUnderline } from '../underline'
|
|
36
37
|
|
|
37
38
|
import { readHtmlTextFromClipboard, readPlainTextFromClipboard } from './clipboard'
|
|
39
|
+
import { renderMathBlock, renderMathInline } from './katex'
|
|
38
40
|
|
|
39
41
|
/**
|
|
40
42
|
* @internal
|
|
@@ -63,6 +65,7 @@ export function defineTestExtension() {
|
|
|
63
65
|
defineHorizontalRule(),
|
|
64
66
|
defineHardBreak(),
|
|
65
67
|
defineCodeBlock(),
|
|
68
|
+
defineMath({ renderMathBlock, renderMathInline }),
|
|
66
69
|
)
|
|
67
70
|
}
|
|
68
71
|
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { render } from 'katex'
|
|
2
|
+
|
|
3
|
+
export function renderMathBlock(text: string, element: HTMLElement) {
|
|
4
|
+
render(text, element, { displayMode: true, throwOnError: false, output: 'mathml' })
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export function renderMathInline(text: string, element: HTMLElement) {
|
|
8
|
+
render(text, element, { displayMode: false, throwOnError: false, output: 'mathml' })
|
|
9
|
+
}
|
package/src/yjs/yjs-types.ts
CHANGED
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
import { OBJECT_REPLACEMENT_CHARACTER, defineFacet, defineFacetPayload, getNodeType, isTextSelection, maybeRun, pluginFacet } from "@prosekit/core";
|
|
2
|
-
import { PluginKey, ProseMirrorPlugin } from "@prosekit/pm/state";
|
|
3
|
-
import { keydownHandler } from "@prosekit/pm/keymap";
|
|
4
|
-
|
|
5
|
-
//#region src/enter-rule/index.ts
|
|
6
|
-
/**
|
|
7
|
-
* Defines an enter rule. An enter rule applies when the text directly in front of
|
|
8
|
-
* the cursor matches `regex` and user presses Enter. The `regex` should end
|
|
9
|
-
* with `$`.
|
|
10
|
-
*
|
|
11
|
-
* @param options
|
|
12
|
-
*
|
|
13
|
-
* @public
|
|
14
|
-
*/
|
|
15
|
-
function defineEnterRule({ regex, handler, stop = false }) {
|
|
16
|
-
return defineFacetPayload(enterRule, [new EnterRule(regex, handler, stop)]);
|
|
17
|
-
}
|
|
18
|
-
/**
|
|
19
|
-
* Defines an enter rule that replaces the matched text with a block node.
|
|
20
|
-
*
|
|
21
|
-
* See also {@link defineEnterRule}.
|
|
22
|
-
*
|
|
23
|
-
* @param options
|
|
24
|
-
*
|
|
25
|
-
* @public
|
|
26
|
-
*/
|
|
27
|
-
function defineTextBlockEnterRule({ regex, type, attrs, stop = true }) {
|
|
28
|
-
return defineEnterRule({
|
|
29
|
-
regex,
|
|
30
|
-
handler: ({ state, from, to, match }) => {
|
|
31
|
-
const nodeType = getNodeType(state.schema, type);
|
|
32
|
-
const $start = state.doc.resolve(from);
|
|
33
|
-
if (!$start.node(-1).canReplaceWith($start.index(-1), $start.indexAfter(-1), nodeType)) return null;
|
|
34
|
-
const nodeAttrs = maybeRun(attrs, match);
|
|
35
|
-
return state.tr.delete(from, to).setBlockType(from, from, nodeType, nodeAttrs);
|
|
36
|
-
},
|
|
37
|
-
stop
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
* @internal
|
|
42
|
-
*/
|
|
43
|
-
var EnterRule = class {
|
|
44
|
-
constructor(regex, handler, stop) {
|
|
45
|
-
this.regex = regex;
|
|
46
|
-
this.handler = handler;
|
|
47
|
-
this.stop = stop;
|
|
48
|
-
}
|
|
49
|
-
};
|
|
50
|
-
const enterRule = defineFacet({
|
|
51
|
-
reduce: () => {
|
|
52
|
-
let rules = [];
|
|
53
|
-
const command = (state, dispatch, view) => {
|
|
54
|
-
if (!view) return false;
|
|
55
|
-
return execRules(view, rules, dispatch);
|
|
56
|
-
};
|
|
57
|
-
const handler = keydownHandler({ Enter: command });
|
|
58
|
-
const plugin = new ProseMirrorPlugin({
|
|
59
|
-
key: new PluginKey("prosekit-enter-rule"),
|
|
60
|
-
props: { handleKeyDown: handler }
|
|
61
|
-
});
|
|
62
|
-
return function reducer(inputs) {
|
|
63
|
-
rules = inputs;
|
|
64
|
-
return plugin;
|
|
65
|
-
};
|
|
66
|
-
},
|
|
67
|
-
parent: pluginFacet
|
|
68
|
-
});
|
|
69
|
-
function execRules(view, rules, dispatch) {
|
|
70
|
-
if (view.composing) return false;
|
|
71
|
-
const state = view.state;
|
|
72
|
-
const selection = state.selection;
|
|
73
|
-
if (!isTextSelection(selection)) return false;
|
|
74
|
-
const $cursor = selection.$cursor;
|
|
75
|
-
if (!$cursor || $cursor.parent.type.spec.code) return false;
|
|
76
|
-
const textBefore = $cursor.parent.textBetween(Math.max(0, $cursor.parentOffset - MAX_MATCH), $cursor.parentOffset, null, OBJECT_REPLACEMENT_CHARACTER);
|
|
77
|
-
for (const rule of rules) {
|
|
78
|
-
rule.regex.lastIndex = 0;
|
|
79
|
-
const match = rule.regex.exec(textBefore);
|
|
80
|
-
const tr = match && rule.handler({
|
|
81
|
-
state,
|
|
82
|
-
from: $cursor.pos - match[0].length,
|
|
83
|
-
to: $cursor.pos,
|
|
84
|
-
match
|
|
85
|
-
});
|
|
86
|
-
if (!tr) continue;
|
|
87
|
-
dispatch?.(tr);
|
|
88
|
-
if (rule.stop) return true;
|
|
89
|
-
}
|
|
90
|
-
return false;
|
|
91
|
-
}
|
|
92
|
-
const MAX_MATCH = 200;
|
|
93
|
-
|
|
94
|
-
//#endregion
|
|
95
|
-
export { defineTextBlockEnterRule as n, defineEnterRule as t };
|
|
96
|
-
//# sourceMappingURL=enter-rule-D-p4ykfv.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"enter-rule-D-p4ykfv.js","names":[],"sources":["../src/enter-rule/index.ts"],"sourcesContent":["import {\n defineFacet,\n defineFacetPayload,\n getNodeType,\n isTextSelection,\n maybeRun,\n OBJECT_REPLACEMENT_CHARACTER,\n pluginFacet,\n type PlainExtension,\n type PluginPayload,\n} from '@prosekit/core'\nimport { keydownHandler } from '@prosekit/pm/keymap'\nimport type { Attrs, NodeType } from '@prosekit/pm/model'\nimport { PluginKey, ProseMirrorPlugin, type Command, type EditorState, type Transaction } from '@prosekit/pm/state'\nimport type { EditorView } from '@prosekit/pm/view'\n\n/**\n * @public\n *\n * Options for {@link EnterRuleHandler}.\n */\nexport interface EnterRuleHandlerOptions {\n /**\n * The current editor state.\n */\n state: EditorState\n\n /**\n * The start position of the matched text.\n */\n from: number\n\n /**\n * The end position of the matched text.\n */\n to: number\n\n /**\n * The matched result from the regular expression.\n */\n match: RegExpExecArray\n}\n\n/**\n * @public\n */\nexport type EnterRuleHandler = (options: EnterRuleHandlerOptions) => Transaction | null\n\n/**\n * Options for {@link defineEnterRule}.\n *\n * @public\n */\nexport type EnterRuleOptions = {\n /**\n * The regular expression to match against. It should end with `$`.\n */\n regex: RegExp\n\n /**\n * A function to be called when an enter rule is triggered.\n */\n handler: EnterRuleHandler\n\n /**\n * Whether to stop further handlers from being called if this rule is triggered.\n *\n * @default false\n */\n stop?: boolean\n}\n\n/**\n * Options for {@link defineTextBlockEnterRule}.\n *\n * @public\n */\nexport interface TextBlockEnterRuleOptions {\n /**\n * The regular expression to match against. It should end with `$`.\n */\n regex: RegExp\n\n /**\n * The node type to replace the matched text with.\n */\n type: string | NodeType\n\n /**\n * Attributes to set on the node. If a function is provided, it will be called\n * with the matched result from the regular expression.\n */\n attrs?: Attrs | null | ((match: RegExpMatchArray) => Attrs | null)\n\n /**\n * Whether to stop further handlers from being called if this rule is triggered.\n *\n * @default true\n */\n stop?: boolean\n}\n\n/**\n * Defines an enter rule. An enter rule applies when the text directly in front of\n * the cursor matches `regex` and user presses Enter. The `regex` should end\n * with `$`.\n *\n * @param options\n *\n * @public\n */\nexport function defineEnterRule({\n regex,\n handler,\n stop = false,\n}: EnterRuleOptions): PlainExtension {\n const rule: EnterRule = new EnterRule(regex, handler, stop)\n return defineFacetPayload(enterRule, [rule]) as PlainExtension\n}\n\n/**\n * Defines an enter rule that replaces the matched text with a block node.\n *\n * See also {@link defineEnterRule}.\n *\n * @param options\n *\n * @public\n */\nexport function defineTextBlockEnterRule({\n regex,\n type,\n attrs,\n stop = true,\n}: TextBlockEnterRuleOptions): PlainExtension {\n return defineEnterRule({\n regex,\n handler: ({ state, from, to, match }) => {\n const nodeType = getNodeType(state.schema, type)\n const $start = state.doc.resolve(from)\n\n if (\n !$start\n .node(-1)\n .canReplaceWith($start.index(-1), $start.indexAfter(-1), nodeType)\n ) {\n return null\n }\n\n const nodeAttrs = maybeRun(attrs, match)\n return state.tr\n .delete(from, to)\n .setBlockType(from, from, nodeType, nodeAttrs)\n },\n stop,\n })\n}\n\n/**\n * @internal\n */\nclass EnterRule {\n constructor(\n readonly regex: RegExp,\n readonly handler: EnterRuleHandler,\n readonly stop: boolean,\n ) {}\n}\n\nconst enterRule = defineFacet<EnterRule, PluginPayload>({\n reduce: () => {\n let rules: EnterRule[] = []\n\n const command: Command = (state, dispatch, view) => {\n if (!view) return false\n return execRules(view, rules, dispatch)\n }\n const handler = keydownHandler({ Enter: command })\n const plugin = new ProseMirrorPlugin({\n key: new PluginKey('prosekit-enter-rule'),\n props: { handleKeyDown: handler },\n })\n\n return function reducer(inputs) {\n rules = inputs\n return plugin\n }\n },\n\n parent: pluginFacet,\n})\n\nfunction execRules(\n view: EditorView,\n rules: readonly EnterRule[],\n dispatch?: (tr: Transaction) => void,\n): boolean {\n if (view.composing) return false\n const state = view.state\n const selection = state.selection\n if (!isTextSelection(selection)) return false\n const $cursor = selection.$cursor\n if (!$cursor || $cursor.parent.type.spec.code) return false\n\n const textBefore = $cursor.parent.textBetween(\n Math.max(0, $cursor.parentOffset - MAX_MATCH),\n $cursor.parentOffset,\n null,\n OBJECT_REPLACEMENT_CHARACTER,\n )\n\n for (const rule of rules) {\n rule.regex.lastIndex = 0\n const match = rule.regex.exec(textBefore)\n const tr = match\n && rule.handler({\n state,\n from: $cursor.pos - match[0].length,\n to: $cursor.pos,\n match,\n })\n if (!tr) continue\n dispatch?.(tr)\n\n if (rule.stop) {\n return true\n }\n }\n return false\n}\n\nconst MAX_MATCH = 200\n"],"mappings":";;;;;;;;;;;;;;AA+GA,SAAgB,gBAAgB,EAC9B,OACA,SACA,OAAO,SAC4B;AAEnC,QAAO,mBAAmB,WAAW,CADb,IAAI,UAAU,OAAO,SAAS,KAAK,CAChB,CAAC;;;;;;;;;;;AAY9C,SAAgB,yBAAyB,EACvC,OACA,MACA,OACA,OAAO,QACqC;AAC5C,QAAO,gBAAgB;EACrB;EACA,UAAU,EAAE,OAAO,MAAM,IAAI,YAAY;GACvC,MAAM,WAAW,YAAY,MAAM,QAAQ,KAAK;GAChD,MAAM,SAAS,MAAM,IAAI,QAAQ,KAAK;AAEtC,OACE,CAAC,OACE,KAAK,GAAG,CACR,eAAe,OAAO,MAAM,GAAG,EAAE,OAAO,WAAW,GAAG,EAAE,SAAS,CAEpE,QAAO;GAGT,MAAM,YAAY,SAAS,OAAO,MAAM;AACxC,UAAO,MAAM,GACV,OAAO,MAAM,GAAG,CAChB,aAAa,MAAM,MAAM,UAAU,UAAU;;EAElD;EACD,CAAC;;;;;AAMJ,IAAM,YAAN,MAAgB;CACd,YACE,AAAS,OACT,AAAS,SACT,AAAS,MACT;EAHS;EACA;EACA;;;AAIb,MAAM,YAAY,YAAsC;CACtD,cAAc;EACZ,IAAI,QAAqB,EAAE;EAE3B,MAAM,WAAoB,OAAO,UAAU,SAAS;AAClD,OAAI,CAAC,KAAM,QAAO;AAClB,UAAO,UAAU,MAAM,OAAO,SAAS;;EAEzC,MAAM,UAAU,eAAe,EAAE,OAAO,SAAS,CAAC;EAClD,MAAM,SAAS,IAAI,kBAAkB;GACnC,KAAK,IAAI,UAAU,sBAAsB;GACzC,OAAO,EAAE,eAAe,SAAS;GAClC,CAAC;AAEF,SAAO,SAAS,QAAQ,QAAQ;AAC9B,WAAQ;AACR,UAAO;;;CAIX,QAAQ;CACT,CAAC;AAEF,SAAS,UACP,MACA,OACA,UACS;AACT,KAAI,KAAK,UAAW,QAAO;CAC3B,MAAM,QAAQ,KAAK;CACnB,MAAM,YAAY,MAAM;AACxB,KAAI,CAAC,gBAAgB,UAAU,CAAE,QAAO;CACxC,MAAM,UAAU,UAAU;AAC1B,KAAI,CAAC,WAAW,QAAQ,OAAO,KAAK,KAAK,KAAM,QAAO;CAEtD,MAAM,aAAa,QAAQ,OAAO,YAChC,KAAK,IAAI,GAAG,QAAQ,eAAe,UAAU,EAC7C,QAAQ,cACR,MACA,6BACD;AAED,MAAK,MAAM,QAAQ,OAAO;AACxB,OAAK,MAAM,YAAY;EACvB,MAAM,QAAQ,KAAK,MAAM,KAAK,WAAW;EACzC,MAAM,KAAK,SACN,KAAK,QAAQ;GACd;GACA,MAAM,QAAQ,MAAM,MAAM,GAAG;GAC7B,IAAI,QAAQ;GACZ;GACD,CAAC;AACJ,MAAI,CAAC,GAAI;AACT,aAAW,GAAG;AAEd,MAAI,KAAK,KACP,QAAO;;AAGX,QAAO;;AAGT,MAAM,YAAY"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"file-iLVR0eM0.js","names":["facet","getFiles"],"sources":["../src/file/helpers.ts","../src/file/file-drop-handler.ts","../src/file/file-paste-handler.ts","../src/file/file-upload.ts"],"sourcesContent":["import type { EditorView } from '@prosekit/pm/view'\n\ntype FileHandler<E extends Event> = (options: {\n view: EditorView\n event: E\n file: File\n}) => boolean | void\n\nfunction handleFile<E extends Event>(\n view: EditorView,\n event: E,\n file: File,\n handlers: FileHandler<E>[],\n) {\n // The last item in `handlers` should has the highest priority.\n for (let i = handlers.length - 1; i >= 0; i--) {\n const handler = handlers[i]\n if (handler({ view, event, file })) {\n return true\n }\n }\n return false\n}\n\nexport function handleEvent<E extends Event>(\n view: EditorView,\n event: E,\n handlers: FileHandler<E>[],\n getFiles: (event: E) => File[],\n): boolean {\n const files = getFiles(event)\n let handled = false\n for (const file of files) {\n if (handleFile(view, event, file, handlers)) {\n handled = true\n }\n }\n return handled\n}\n","import {\n defineFacet,\n defineFacetPayload,\n editorEventFacet,\n type DropHandler,\n type EditorEventPayload,\n type PlainExtension,\n} from '@prosekit/core'\nimport type { EditorView } from '@prosekit/pm/view'\n\nimport { handleEvent } from './helpers'\n\nexport interface FileDropHandlerOptions {\n /**\n * The editor view.\n */\n view: EditorView\n\n /**\n * The event that triggered the drop.\n */\n event: DragEvent\n\n /**\n * The file that was dropped.\n */\n file: File\n\n /**\n * The position of the document where the file was dropped.\n */\n pos: number\n}\n\n/**\n * A function that handles one of the files in a drop event.\n *\n * Returns `true` if the file was handled and thus should not be handled by\n * other handlers.\n */\nexport type FileDropHandler = (\n options: FileDropHandlerOptions,\n) => boolean | void\n\nexport function defineFileDropHandler(\n handler: FileDropHandler,\n): PlainExtension {\n return defineFacetPayload(facet, [handler]) as PlainExtension\n}\n\nfunction getFiles(event: DragEvent) {\n return Array.from(event.dataTransfer?.files ?? [])\n}\n\nconst facet = defineFacet<FileDropHandler, EditorEventPayload>({\n parent: editorEventFacet,\n singleton: true,\n reducer: (handlers: FileDropHandler[]): EditorEventPayload => {\n const dropHandler: DropHandler = (view, event): boolean => {\n const position = view.posAtCoords({ left: event.x, top: event.y })\n if (!position) {\n return false\n }\n const pos = position.inside > 0 ? position.inside : position.pos\n\n return handleEvent<DragEvent>(\n view,\n event,\n handlers.map((handler) => (options) => handler({ ...options, pos })),\n getFiles,\n )\n }\n return ['drop', dropHandler]\n },\n})\n","import {\n defineFacet,\n defineFacetPayload,\n editorEventFacet,\n type EditorEventPayload,\n type PasteHandler,\n type PlainExtension,\n} from '@prosekit/core'\nimport type { EditorView } from '@prosekit/pm/view'\n\nimport { handleEvent } from './helpers'\n\nexport interface FilePasteHandlerOptions {\n /**\n * The editor view.\n */\n view: EditorView\n\n /**\n * The event that triggered the paste.\n */\n event: ClipboardEvent\n\n /**\n * The file that was pasted.\n */\n file: File\n}\n\n/**\n * A function that handles one of the files in a paste event.\n *\n * Returns `true` if the file was handled and thus should not be handled by\n * other handlers.\n */\nexport type FilePasteHandler = (\n options: FilePasteHandlerOptions,\n) => boolean | void\n\nexport function defineFilePasteHandler(\n handler: FilePasteHandler,\n): PlainExtension {\n return defineFacetPayload(facet, [handler]) as PlainExtension\n}\n\nfunction getFiles(event: ClipboardEvent) {\n return Array.from(event.clipboardData?.files ?? [])\n}\n\nconst facet = defineFacet<FilePasteHandler, EditorEventPayload>({\n parent: editorEventFacet,\n singleton: true,\n reducer: (handlers: FilePasteHandler[]): EditorEventPayload => {\n const pasteHandler: PasteHandler = (view, event): boolean => {\n return handleEvent<ClipboardEvent>(view, event, handlers, getFiles)\n }\n return ['paste', pasteHandler]\n },\n})\n","import { ProseKitError } from '@prosekit/core'\n\n/**\n * An interface representing the upload progress.\n */\nexport interface UploadProgress {\n // A number representing the amount of work already performed by the\n // underlying process.\n loaded: number\n // A number representing the total amount of work that the underlying\n // process is in the progress of performing.\n total: number\n}\n\nexport interface UploaderOptions {\n /**\n * The file to be uploaded.\n */\n file: File\n\n /**\n * A callback function that should be called with the upload progress updates.\n */\n onProgress: (progress: UploadProgress) => void\n}\n\n/**\n * The implementation of the actual upload function. You need to implement this\n * function to upload files to your desired destination.\n */\nexport type Uploader<Result> = (options: UploaderOptions) => Promise<Result>\n\n/**\n * A class that represents a upload task.\n */\nexport class UploadTask<Result> {\n /**\n * An [object URL](https://developer.mozilla.org/en-US/docs/Web/API/URL/createObjectURL)\n * representing the file to be uploaded. This URL will be revoked once the\n * upload is complete successfully.\n */\n readonly objectURL: string\n\n /**\n * A boolean indicating whether the upload is complete (either successfully or with an error).\n */\n protected done = false\n\n /**\n * If the upload is complete successfully, this will be the result of the upload.\n */\n protected result: Result | undefined\n\n /**\n * If the upload is complete with an error, this will be the error that occurred.\n */\n protected error: Error | undefined\n\n /**\n * A promise that fulfills once the upload is complete, or rejects if an error occurs.\n */\n readonly finished: Promise<Result>\n\n private subscribers: ((progress: UploadProgress) => void)[] = []\n\n /**\n * Creates a new upload task. You can find the upload task by its object URL\n * later using `UploadTask.get()`.\n *\n * @param options - The options for the upload task.\n */\n constructor({ file, uploader }: { file: File; uploader: Uploader<Result> }) {\n this.objectURL = URL.createObjectURL(file)\n this.finished = new Promise((resolve, reject) => {\n const maybePromise = uploader({\n file,\n onProgress: (progress) => {\n for (const subscriber of this.subscribers) {\n subscriber(progress)\n }\n },\n })\n Promise.resolve(maybePromise).then(\n (result) => {\n this.done = true\n URL.revokeObjectURL(this.objectURL)\n this.result = result\n resolve(result)\n },\n (err) => {\n this.done = true\n const error = new ProseKitError('[prosekit] Failed to upload file', { cause: err })\n this.error = error\n reject(error)\n },\n )\n })\n store.set(this.objectURL, this)\n }\n\n /**\n * Subscribes to progress updates. Returns a function to unsubscribe.\n */\n public subscribeProgress(\n callback: (progress: UploadProgress) => void,\n ): VoidFunction {\n this.subscribers.push(callback)\n return () => {\n this.subscribers = this.subscribers.filter(\n (subscriber) => subscriber !== callback,\n )\n }\n }\n\n /**\n * Finds an upload task from the global store by its object URL.\n */\n static get<Result = unknown>(\n objectURL: string,\n ): UploadTask<Result> | undefined {\n return store.get(objectURL) as UploadTask<Result> | undefined\n }\n\n /**\n * Deletes an upload task from the global store by its object URL.\n */\n static delete(objectURL: string): void {\n store.delete(objectURL)\n }\n}\n\nconst store = new Map<string, UploadTask<unknown>>()\n"],"mappings":";;;AAQA,SAAS,WACP,MACA,OACA,MACA,UACA;AAEA,MAAK,IAAI,IAAI,SAAS,SAAS,GAAG,KAAK,GAAG,KAAK;EAC7C,MAAM,UAAU,SAAS;AACzB,MAAI,QAAQ;GAAE;GAAM;GAAO;GAAM,CAAC,CAChC,QAAO;;AAGX,QAAO;;AAGT,SAAgB,YACd,MACA,OACA,UACA,UACS;CACT,MAAM,QAAQ,SAAS,MAAM;CAC7B,IAAI,UAAU;AACd,MAAK,MAAM,QAAQ,MACjB,KAAI,WAAW,MAAM,OAAO,MAAM,SAAS,CACzC,WAAU;AAGd,QAAO;;;;;ACOT,SAAgB,sBACd,SACgB;AAChB,QAAO,mBAAmBA,SAAO,CAAC,QAAQ,CAAC;;AAG7C,SAASC,WAAS,OAAkB;AAClC,QAAO,MAAM,KAAK,MAAM,cAAc,SAAS,EAAE,CAAC;;AAGpD,MAAMD,UAAQ,YAAiD;CAC7D,QAAQ;CACR,WAAW;CACX,UAAU,aAAoD;EAC5D,MAAM,eAA4B,MAAM,UAAmB;GACzD,MAAM,WAAW,KAAK,YAAY;IAAE,MAAM,MAAM;IAAG,KAAK,MAAM;IAAG,CAAC;AAClE,OAAI,CAAC,SACH,QAAO;GAET,MAAM,MAAM,SAAS,SAAS,IAAI,SAAS,SAAS,SAAS;AAE7D,UAAO,YACL,MACA,OACA,SAAS,KAAK,aAAa,YAAY,QAAQ;IAAE,GAAG;IAAS;IAAK,CAAC,CAAC,EACpEC,WACD;;AAEH,SAAO,CAAC,QAAQ,YAAY;;CAE/B,CAAC;;;;ACnCF,SAAgB,uBACd,SACgB;AAChB,QAAO,mBAAmB,OAAO,CAAC,QAAQ,CAAC;;AAG7C,SAAS,SAAS,OAAuB;AACvC,QAAO,MAAM,KAAK,MAAM,eAAe,SAAS,EAAE,CAAC;;AAGrD,MAAM,QAAQ,YAAkD;CAC9D,QAAQ;CACR,WAAW;CACX,UAAU,aAAqD;EAC7D,MAAM,gBAA8B,MAAM,UAAmB;AAC3D,UAAO,YAA4B,MAAM,OAAO,UAAU,SAAS;;AAErE,SAAO,CAAC,SAAS,aAAa;;CAEjC,CAAC;;;;;;;ACvBF,IAAa,aAAb,MAAgC;;;;;;;CAoC9B,YAAY,EAAE,MAAM,YAAwD;cAzB3D;qBAiB6C,EAAE;AAS9D,OAAK,YAAY,IAAI,gBAAgB,KAAK;AAC1C,OAAK,WAAW,IAAI,SAAS,SAAS,WAAW;GAC/C,MAAM,eAAe,SAAS;IAC5B;IACA,aAAa,aAAa;AACxB,UAAK,MAAM,cAAc,KAAK,YAC5B,YAAW,SAAS;;IAGzB,CAAC;AACF,WAAQ,QAAQ,aAAa,CAAC,MAC3B,WAAW;AACV,SAAK,OAAO;AACZ,QAAI,gBAAgB,KAAK,UAAU;AACnC,SAAK,SAAS;AACd,YAAQ,OAAO;OAEhB,QAAQ;AACP,SAAK,OAAO;IACZ,MAAM,QAAQ,IAAI,cAAc,oCAAoC,EAAE,OAAO,KAAK,CAAC;AACnF,SAAK,QAAQ;AACb,WAAO,MAAM;KAEhB;IACD;AACF,QAAM,IAAI,KAAK,WAAW,KAAK;;;;;CAMjC,AAAO,kBACL,UACc;AACd,OAAK,YAAY,KAAK,SAAS;AAC/B,eAAa;AACX,QAAK,cAAc,KAAK,YAAY,QACjC,eAAe,eAAe,SAChC;;;;;;CAOL,OAAO,IACL,WACgC;AAChC,SAAO,MAAM,IAAI,UAAU;;;;;CAM7B,OAAO,OAAO,WAAyB;AACrC,QAAM,OAAO,UAAU;;;AAI3B,MAAM,wBAAQ,IAAI,KAAkC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index-cp1u4e0e.d.ts","names":[],"sources":["../src/file/file-drop-handler.ts","../src/file/file-paste-handler.ts","../src/file/file-upload.ts"],"mappings":";;;;UAYiB,sBAAA;;AAAjB;;EAIE,IAAA,EAAM,UAAA;EAAA;;;EAKN,KAAA,EAAO,SAAA;EAKG;;;EAAV,IAAA,EAAM,IAAA;EALC;;;EAUP,GAAA;AAAA;;AASF;;;;;KAAY,eAAA,IACV,OAAA,EAAS,sBAAA;AAAA,iBAGK,qBAAA,CACd,OAAA,EAAS,eAAA,GACR,cAAA;;;UClCc,uBAAA;;ADAjB;;ECIE,IAAA,EAAM,UAAA;EDAA;;;ECKN,KAAA,EAAO,cAAA;EDKG;;;ECAV,IAAA,EAAM,IAAA;AAAA;;;;;;ADcR;KCLY,gBAAA,IACV,OAAA,EAAS,uBAAA;AAAA,iBAGK,sBAAA,CACd,OAAA,EAAS,gBAAA,GACR,cAAA;;;;;;UCpCc,cAAA;EAGf,MAAA;EAGA,KAAA;AAAA;AAAA,UAGe,eAAA;EFOR;;;EEHP,IAAA,EAAM,IAAA;EFFN;;;EEOA,UAAA,GAAa,QAAA,EAAU,cAAA;AAAA;;;;;KAOb,QAAA,YAAoB,OAAA,EAAS,eAAA,KAAoB,OAAA,CAAQ,MAAA;;;;cAKxD,UAAA;EFSG;;;;;EAAA,SEHL,SAAA;EFKR;;;EAAA,UEAS,IAAA;;;ADlCZ;YCuCY,MAAA,EAAQ,MAAA;;;;YAKR,KAAA,EAAO,KAAA;ED9BP;;;EAAA,SCmCD,QAAA,EAAU,OAAA,CAAQ,MAAA;EAAA,QAEnB,WAAA;ED1CD;;;;;AAcT;;ICoCgB,IAAA;IAAM;EAAA;IAAc,IAAA,EAAM,IAAA;IAAM,QAAA,EAAU,QAAA,CAAS,MAAA;EAAA;EDhCnD;;;ECgEP,iBAAA,CACL,QAAA,GAAW,QAAA,EAAU,cAAA,YACpB,YAAA;EDjEM;;;EAAA,OC6EF,GAAA,kBAAA,CACL,SAAA,WACC,UAAA,CAAW,MAAA;ED9EC;;;EAAA,OCqFR,MAAA,CAAO,SAAA;AAAA"}
|