-
-
Notifications
You must be signed in to change notification settings - Fork 377
/
create-node.ts
113 lines (101 loc) 路 3.97 KB
/
create-node.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
/* Copyright 2021, Milkdown by Mirone. */
import { Ctx, MilkdownPlugin, NodeSchema } from '@milkdown/core';
import { NodeType } from '@milkdown/prose/model';
import { NodeViewConstructor } from '@milkdown/prose/view';
import { pipe } from '../pipe';
import { AnySlice, CommonOptions, Factory, UnknownRecord, WithExtend } from '../types';
import { addMetadata, getThemeUtils, withExtend } from './common';
import {
applyProsePlugins,
applyRemarkPlugins,
applySchema,
applyView,
createCommands,
createInputRules,
createShortcuts,
getCommandsPipeCtx,
getInputRulesPipeCtx,
getProsePluginsPipeCtx,
getRemarkPluginsPipeCtx,
getSchemaPipeCtx,
getViewPipeCtx,
idPipeCtx,
injectPipeEnv,
injectSlices,
optionsPipeCtx,
shortcutsPipeCtx,
waitThemeReady,
} from './pieces';
import { Pipeline, run } from './pipeline';
export type NodeRest = {
id: string;
schema: (ctx: Ctx) => NodeSchema;
view?: (ctx: Ctx) => NodeViewConstructor;
};
export type NodeFactory<SupportedKeys extends string, Options extends UnknownRecord> = Factory<
SupportedKeys,
Options,
NodeType,
NodeRest
>;
export type NodeCreator<
SupportedKeys extends string = string,
Options extends UnknownRecord = UnknownRecord,
> = WithExtend<SupportedKeys, Options, NodeType, NodeRest>;
export const createNode = <SupportedKeys extends string = string, Options extends UnknownRecord = UnknownRecord>(
factory: NodeFactory<SupportedKeys, Options>,
inject?: AnySlice[],
): NodeCreator<SupportedKeys, Options> =>
pipe(
addMetadata,
withExtend(factory, createNode),
)(
(options?: Partial<CommonOptions<SupportedKeys, Options>>): MilkdownPlugin =>
(pre) =>
async (ctx) => {
const setPipelineEnv: Pipeline = async ({ pipelineCtx }, next) => {
const utils = getThemeUtils(ctx, options);
const plugin = factory(utils, options);
const { id, commands, remarkPlugins, schema, inputRules, shortcuts, prosePlugins, view } = plugin;
const viewOption = options?.view;
const pluginOptions = {
...(options || {}),
view: viewOption ? (ctx: Ctx) => ({ [id]: viewOption(ctx) }) : undefined,
};
pipelineCtx.set(idPipeCtx, id);
pipelineCtx.set(optionsPipeCtx, pluginOptions);
pipelineCtx.set(getRemarkPluginsPipeCtx, remarkPlugins);
pipelineCtx.set(getSchemaPipeCtx, (ctx) => ({ node: { [id]: schema(ctx) } }));
if (commands) {
pipelineCtx.set(getCommandsPipeCtx, (type, ctx) => commands(type[id] as NodeType, ctx));
}
if (inputRules) {
pipelineCtx.set(getInputRulesPipeCtx, (type, ctx) => inputRules(type[id] as NodeType, ctx));
}
if (shortcuts) {
pipelineCtx.set(shortcutsPipeCtx, shortcuts);
}
if (prosePlugins) {
pipelineCtx.set(getProsePluginsPipeCtx, (type, ctx) => prosePlugins(type[id] as NodeType, ctx));
}
if (view) {
pipelineCtx.set(getViewPipeCtx, (ctx) => ({ [id]: view(ctx) }));
}
await next();
};
const runner = run([
injectPipeEnv,
injectSlices(inject),
waitThemeReady,
setPipelineEnv,
applyRemarkPlugins,
applySchema,
createCommands,
createInputRules,
createShortcuts,
applyProsePlugins,
applyView,
]);
await runner(pre, ctx);
},
);