@prosekit/extensions 0.7.1 → 0.7.3
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/_tsup-dts-rollup.d.ts +100 -120
- package/dist/chunk-GPSAJOJA.js +188 -0
- package/dist/{chunk-PYT3MOTF.js → chunk-LVMTQOWG.js} +31 -14
- package/dist/{chunk-2JYT2MT7.js → chunk-OJCMRVEY.js} +36 -21
- package/dist/list/style.css +9 -5
- package/dist/placeholder/style.css +1 -1
- package/dist/prosekit-extensions-autocomplete.js +62 -33
- package/dist/prosekit-extensions-blockquote.js +2 -2
- package/dist/prosekit-extensions-bold.js +7 -3
- package/dist/prosekit-extensions-code-block.js +77 -41
- package/dist/prosekit-extensions-code.js +1 -1
- package/dist/prosekit-extensions-commit.js +70 -30
- package/dist/prosekit-extensions-enter-rule.js +1 -1
- package/dist/prosekit-extensions-heading.d.ts +4 -4
- package/dist/prosekit-extensions-heading.js +66 -36
- package/dist/prosekit-extensions-image.js +14 -5
- package/dist/prosekit-extensions-input-rule.js +1 -1
- package/dist/prosekit-extensions-italic.js +1 -1
- package/dist/prosekit-extensions-link.js +27 -14
- package/dist/prosekit-extensions-list.d.ts +8 -2
- package/dist/prosekit-extensions-list.js +64 -35
- package/dist/prosekit-extensions-mark-rule.js +1 -1
- package/dist/prosekit-extensions-mention.js +6 -4
- package/dist/prosekit-extensions-placeholder.js +16 -7
- package/dist/prosekit-extensions-readonly.js +1 -1
- package/dist/prosekit-extensions-search.js +8 -5
- package/dist/prosekit-extensions-strike.js +1 -1
- package/dist/prosekit-extensions-table.js +68 -30
- package/dist/prosekit-extensions-text-align.js +4 -2
- package/dist/prosekit-extensions-virtual-selection.js +11 -6
- package/package.json +8 -8
- package/dist/chunk-ZPEMHYTU.js +0 -140
@@ -16,24 +16,26 @@ import {
|
|
16
16
|
function defineEnterRule({
|
17
17
|
regex,
|
18
18
|
handler,
|
19
|
-
stop =
|
19
|
+
stop = false
|
20
20
|
}) {
|
21
|
-
|
21
|
+
const rule = new EnterRule(regex, handler, stop);
|
22
22
|
return defineFacetPayload(enterRule, [rule]);
|
23
23
|
}
|
24
24
|
function defineTextBlockEnterRule({
|
25
25
|
regex,
|
26
26
|
type,
|
27
27
|
attrs,
|
28
|
-
stop =
|
28
|
+
stop = true
|
29
29
|
}) {
|
30
30
|
return defineEnterRule({
|
31
31
|
regex,
|
32
32
|
handler: ({ state, from, to, match }) => {
|
33
|
-
|
34
|
-
|
33
|
+
const nodeType = getNodeType(state.schema, type);
|
34
|
+
const $start = state.doc.resolve(from);
|
35
|
+
if (!$start.node(-1).canReplaceWith($start.index(-1), $start.indexAfter(-1), nodeType)) {
|
35
36
|
return null;
|
36
|
-
|
37
|
+
}
|
38
|
+
const nodeAttrs = maybeRun(attrs, match);
|
37
39
|
return state.tr.delete(from, to).setBlockType(from, from, nodeType, nodeAttrs);
|
38
40
|
},
|
39
41
|
stop
|
@@ -45,42 +47,55 @@ var EnterRule = class {
|
|
45
47
|
this.handler = handler;
|
46
48
|
this.stop = stop;
|
47
49
|
}
|
48
|
-
}
|
50
|
+
};
|
51
|
+
var enterRule = defineFacet({
|
49
52
|
reduce: () => {
|
50
|
-
let rules = []
|
53
|
+
let rules = [];
|
54
|
+
const command = (state, dispatch, view) => {
|
55
|
+
if (!view) return false;
|
56
|
+
return execRules(view, rules, dispatch);
|
57
|
+
};
|
58
|
+
const handler = keydownHandler({ Enter: command });
|
59
|
+
const plugin = new ProseMirrorPlugin({
|
51
60
|
key: new PluginKey("prosekit-enter-rule"),
|
52
61
|
props: { handleKeyDown: handler }
|
53
62
|
});
|
54
|
-
return function(inputs) {
|
55
|
-
|
63
|
+
return function reducer(inputs) {
|
64
|
+
rules = inputs;
|
65
|
+
return plugin;
|
56
66
|
};
|
57
67
|
},
|
58
68
|
parent: pluginFacet
|
59
69
|
});
|
60
70
|
function execRules(view, rules, dispatch) {
|
61
|
-
if (view.composing) return
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
71
|
+
if (view.composing) return false;
|
72
|
+
const state = view.state;
|
73
|
+
const selection = state.selection;
|
74
|
+
if (!isTextSelection(selection)) return false;
|
75
|
+
const $cursor = selection.$cursor;
|
76
|
+
if (!$cursor || $cursor.parent.type.spec.code) return false;
|
77
|
+
const textBefore = $cursor.parent.textBetween(
|
67
78
|
Math.max(0, $cursor.parentOffset - MAX_MATCH),
|
68
79
|
$cursor.parentOffset,
|
69
80
|
null,
|
70
81
|
OBJECT_REPLACEMENT_CHARACTER
|
71
82
|
);
|
72
|
-
for (
|
83
|
+
for (const rule of rules) {
|
73
84
|
rule.regex.lastIndex = 0;
|
74
|
-
|
85
|
+
const match = rule.regex.exec(textBefore);
|
86
|
+
const tr = match && rule.handler({
|
75
87
|
state,
|
76
88
|
from: $cursor.pos - match[0].length,
|
77
89
|
to: $cursor.pos,
|
78
90
|
match
|
79
91
|
});
|
80
|
-
if (tr
|
81
|
-
|
92
|
+
if (!tr) continue;
|
93
|
+
dispatch == null ? void 0 : dispatch(tr);
|
94
|
+
if (rule.stop) {
|
95
|
+
return true;
|
96
|
+
}
|
82
97
|
}
|
83
|
-
return
|
98
|
+
return false;
|
84
99
|
}
|
85
100
|
var MAX_MATCH = 200;
|
86
101
|
|
package/dist/list/style.css
CHANGED
@@ -1,7 +1,8 @@
|
|
1
|
-
/* ../../node_modules/.pnpm/prosemirror-flat-list@0.5.
|
1
|
+
/* ../../node_modules/.pnpm/prosemirror-flat-list@0.5.2/node_modules/prosemirror-flat-list/dist/style.css */
|
2
2
|
.prosemirror-flat-list {
|
3
3
|
padding: 0;
|
4
4
|
margin-top: 0;
|
5
|
+
margin-bottom: 0;
|
5
6
|
margin-left: 32px;
|
6
7
|
margin-bottom: 0;
|
7
8
|
position: relative;
|
@@ -14,7 +15,10 @@
|
|
14
15
|
.prosemirror-flat-list.ProseMirror-selectednode:after {
|
15
16
|
content: "";
|
16
17
|
position: absolute;
|
17
|
-
|
18
|
+
left: -32px;
|
19
|
+
right: -2px;
|
20
|
+
top: -2px;
|
21
|
+
bottom: -2px;
|
18
22
|
border: 2px solid #8cf;
|
19
23
|
pointer-events: none;
|
20
24
|
}
|
@@ -27,7 +31,7 @@
|
|
27
31
|
.prosemirror-flat-list[data-list-kind=ordered] > * {
|
28
32
|
contain: style;
|
29
33
|
}
|
30
|
-
.prosemirror-flat-list[data-list-kind=ordered]
|
34
|
+
.prosemirror-flat-list[data-list-kind=ordered]::before {
|
31
35
|
position: absolute;
|
32
36
|
right: 100%;
|
33
37
|
font-variant-numeric: tabular-nums;
|
@@ -65,10 +69,10 @@
|
|
65
69
|
width: 1.5em;
|
66
70
|
width: 1lh;
|
67
71
|
}
|
68
|
-
.prosemirror-flat-list[data-list-kind=toggle] > .list-marker
|
72
|
+
.prosemirror-flat-list[data-list-kind=toggle] > .list-marker::before {
|
69
73
|
content: "\23f7";
|
70
74
|
}
|
71
|
-
.prosemirror-flat-list[data-list-kind=toggle][data-list-collapsable][data-list-collapsed] > .list-marker
|
75
|
+
.prosemirror-flat-list[data-list-kind=toggle][data-list-collapsable][data-list-collapsed] > .list-marker::before {
|
72
76
|
content: "\23f5";
|
73
77
|
}
|
74
78
|
.prosemirror-flat-list[data-list-kind=toggle][data-list-collapsable] > .list-marker {
|
@@ -17,9 +17,11 @@ function defaultCanMatch({ state }) {
|
|
17
17
|
return state.selection.empty && !isInsideCode(state.selection.$from);
|
18
18
|
}
|
19
19
|
function isInsideCode($pos) {
|
20
|
-
for (let d = $pos.depth; d > 0; d--)
|
21
|
-
if ($pos.node(d).type.spec.code)
|
22
|
-
return
|
20
|
+
for (let d = $pos.depth; d > 0; d--) {
|
21
|
+
if ($pos.node(d).type.spec.code) {
|
22
|
+
return true;
|
23
|
+
}
|
24
|
+
}
|
23
25
|
return $pos.marks().some((mark) => mark.type.name === "code");
|
24
26
|
}
|
25
27
|
function getPluginState(state) {
|
@@ -42,39 +44,55 @@ function createAutocompletePlugin({
|
|
42
44
|
return new Plugin({
|
43
45
|
key: pluginKey,
|
44
46
|
state: {
|
45
|
-
init: () =>
|
47
|
+
init: () => {
|
48
|
+
return { active: false, ignore: null, matching: null };
|
49
|
+
},
|
46
50
|
apply: (tr, prevValue, oldState, newState) => {
|
47
51
|
var _a;
|
48
|
-
|
49
|
-
if (!tr.docChanged && oldState.selection.eq(newState.selection) && !meta)
|
52
|
+
const meta = getTrMeta(tr);
|
53
|
+
if (!tr.docChanged && oldState.selection.eq(newState.selection) && !meta) {
|
50
54
|
return prevValue;
|
51
|
-
|
55
|
+
}
|
56
|
+
if (meta) {
|
52
57
|
return meta;
|
53
|
-
|
54
|
-
|
58
|
+
}
|
59
|
+
const nextValue = calcPluginState(newState, getRules());
|
60
|
+
if (nextValue.active && prevValue.ignore != null && ((_a = nextValue.matching) == null ? void 0 : _a.from) === prevValue.ignore) {
|
61
|
+
return prevValue;
|
62
|
+
}
|
63
|
+
return nextValue;
|
55
64
|
}
|
56
65
|
},
|
57
66
|
view: () => ({
|
58
67
|
update: (view, prevState) => {
|
59
68
|
var _a, _b, _c;
|
60
|
-
|
61
|
-
|
62
|
-
|
69
|
+
const prevValue = getPluginState(prevState);
|
70
|
+
const currValue = getPluginState(view.state);
|
71
|
+
if ((prevValue == null ? void 0 : prevValue.active) && prevValue.matching && prevValue.matching.rule !== ((_a = currValue == null ? void 0 : currValue.matching) == null ? void 0 : _a.rule)) {
|
72
|
+
(_c = (_b = prevValue.matching.rule).onLeave) == null ? void 0 : _c.call(_b);
|
73
|
+
}
|
74
|
+
if ((currValue == null ? void 0 : currValue.active) && currValue.matching && currValue.matching.from !== currValue.ignore) {
|
75
|
+
const { from, to, match, rule } = currValue.matching;
|
76
|
+
const textContent = view.state.doc.textBetween(
|
63
77
|
from,
|
64
78
|
to,
|
65
79
|
null,
|
66
80
|
OBJECT_REPLACEMENT_CHARACTER
|
67
|
-
)
|
68
|
-
|
81
|
+
);
|
82
|
+
const deleteMatch = () => {
|
83
|
+
if (view.state.doc.textBetween(
|
69
84
|
from,
|
70
85
|
to,
|
71
86
|
null,
|
72
87
|
OBJECT_REPLACEMENT_CHARACTER
|
73
|
-
) === textContent
|
74
|
-
|
88
|
+
) === textContent) {
|
89
|
+
view.dispatch(view.state.tr.delete(from, to));
|
90
|
+
}
|
91
|
+
};
|
92
|
+
const ignoreMatch = () => {
|
75
93
|
view.dispatch(
|
76
94
|
setTrMeta(view.state.tr, {
|
77
|
-
active:
|
95
|
+
active: false,
|
78
96
|
ignore: from,
|
79
97
|
matching: null
|
80
98
|
})
|
@@ -93,9 +111,10 @@ function createAutocompletePlugin({
|
|
93
111
|
}),
|
94
112
|
props: {
|
95
113
|
decorations: (state) => {
|
96
|
-
|
97
|
-
if (pluginState
|
98
|
-
|
114
|
+
const pluginState = getPluginState(state);
|
115
|
+
if ((pluginState == null ? void 0 : pluginState.active) && pluginState.matching) {
|
116
|
+
const { from, to } = pluginState.matching;
|
117
|
+
const deco = Decoration.inline(from, to, {
|
99
118
|
class: "prosemirror-prediction-match"
|
100
119
|
});
|
101
120
|
return DecorationSet.create(state.doc, [deco]);
|
@@ -107,22 +126,26 @@ function createAutocompletePlugin({
|
|
107
126
|
}
|
108
127
|
var MAX_MATCH = 200;
|
109
128
|
function calcPluginState(state, rules) {
|
110
|
-
|
129
|
+
const $pos = state.selection.$from;
|
130
|
+
const parentOffset = $pos.parentOffset;
|
131
|
+
const textBefore = $pos.parent.textBetween(
|
111
132
|
Math.max(0, parentOffset - MAX_MATCH),
|
112
133
|
parentOffset,
|
113
134
|
null,
|
114
135
|
OBJECT_REPLACEMENT_CHARACTER
|
115
136
|
);
|
116
|
-
for (
|
117
|
-
if (!rule.canMatch({ state }))
|
137
|
+
for (const rule of rules) {
|
138
|
+
if (!rule.canMatch({ state })) {
|
118
139
|
continue;
|
140
|
+
}
|
119
141
|
rule.regex.lastIndex = 0;
|
120
|
-
|
121
|
-
if (!match)
|
142
|
+
const match = rule.regex.exec(textBefore);
|
143
|
+
if (!match) {
|
122
144
|
continue;
|
123
|
-
|
145
|
+
}
|
146
|
+
const from = $pos.pos - textBefore.length + match.index;
|
124
147
|
return {
|
125
|
-
active:
|
148
|
+
active: true,
|
126
149
|
ignore: null,
|
127
150
|
matching: {
|
128
151
|
rule,
|
@@ -132,14 +155,17 @@ function calcPluginState(state, rules) {
|
|
132
155
|
}
|
133
156
|
};
|
134
157
|
}
|
135
|
-
return { active:
|
158
|
+
return { active: false, ignore: null, matching: null };
|
136
159
|
}
|
137
160
|
|
138
161
|
// src/autocomplete/rule.ts
|
139
162
|
var AutocompleteRule = class {
|
140
163
|
constructor(options) {
|
141
164
|
var _a;
|
142
|
-
this.regex = options.regex
|
165
|
+
this.regex = options.regex;
|
166
|
+
this.onMatch = options.onEnter;
|
167
|
+
this.onLeave = options.onLeave;
|
168
|
+
this.canMatch = (_a = options.canMatch) != null ? _a : defaultCanMatch;
|
143
169
|
}
|
144
170
|
};
|
145
171
|
|
@@ -149,13 +175,16 @@ function defineAutocomplete(rule) {
|
|
149
175
|
}
|
150
176
|
var autocompleteFacet = defineFacet({
|
151
177
|
reduce: () => {
|
152
|
-
let rules = []
|
153
|
-
|
154
|
-
|
178
|
+
let rules = [];
|
179
|
+
const getRules = () => rules;
|
180
|
+
const plugin = createAutocompletePlugin({ getRules });
|
181
|
+
return function reducer(inputs) {
|
182
|
+
rules = inputs;
|
183
|
+
return plugin;
|
155
184
|
};
|
156
185
|
},
|
157
186
|
parent: pluginFacet,
|
158
|
-
singleton:
|
187
|
+
singleton: true
|
159
188
|
});
|
160
189
|
export {
|
161
190
|
AutocompleteRule,
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import {
|
2
2
|
defineWrappingInputRule
|
3
|
-
} from "./chunk-
|
3
|
+
} from "./chunk-LVMTQOWG.js";
|
4
4
|
|
5
5
|
// src/blockquote/index.ts
|
6
6
|
import { defineNodeSpec, union } from "@prosekit/core";
|
@@ -9,7 +9,7 @@ function defineBlockquoteSpec() {
|
|
9
9
|
name: "blockquote",
|
10
10
|
content: "block+",
|
11
11
|
group: "block",
|
12
|
-
defining:
|
12
|
+
defining: true,
|
13
13
|
parseDOM: [{ tag: "blockquote" }],
|
14
14
|
toDOM() {
|
15
15
|
return ["blockquote", 0];
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import {
|
2
2
|
defineMarkInputRule
|
3
|
-
} from "./chunk-
|
3
|
+
} from "./chunk-LVMTQOWG.js";
|
4
4
|
|
5
5
|
// src/bold/index.ts
|
6
6
|
import {
|
@@ -21,12 +21,16 @@ function defineBoldSpec() {
|
|
21
21
|
// tags with a font-weight normal.
|
22
22
|
{
|
23
23
|
tag: "b",
|
24
|
-
getAttrs: (node) =>
|
24
|
+
getAttrs: (node) => {
|
25
|
+
return typeof node !== "string" && node.style.fontWeight !== "normal" && null;
|
26
|
+
}
|
25
27
|
},
|
26
28
|
{ style: "font-weight=400", clearMark: (m) => m.type.name == "strong" },
|
27
29
|
{
|
28
30
|
style: "font-weight",
|
29
|
-
getAttrs: (value) =>
|
31
|
+
getAttrs: (value) => {
|
32
|
+
return typeof value === "string" && /^(bold(er)?|[5-9]\d{2,})$/.test(value) && null;
|
33
|
+
}
|
30
34
|
}
|
31
35
|
],
|
32
36
|
toDOM() {
|
@@ -1,9 +1,9 @@
|
|
1
1
|
import {
|
2
2
|
defineTextBlockEnterRule
|
3
|
-
} from "./chunk-
|
3
|
+
} from "./chunk-OJCMRVEY.js";
|
4
4
|
import {
|
5
5
|
defineTextBlockInputRule
|
6
|
-
} from "./chunk-
|
6
|
+
} from "./chunk-LVMTQOWG.js";
|
7
7
|
|
8
8
|
// src/code-block/code-block.ts
|
9
9
|
import { union } from "@prosekit/core";
|
@@ -18,10 +18,18 @@ import {
|
|
18
18
|
} from "@prosekit/core";
|
19
19
|
function defineCodeBlockCommands() {
|
20
20
|
return defineCommands({
|
21
|
-
setCodeBlock: (attrs) =>
|
22
|
-
|
23
|
-
|
24
|
-
|
21
|
+
setCodeBlock: (attrs) => {
|
22
|
+
return setBlockType({ type: "codeBlock", attrs });
|
23
|
+
},
|
24
|
+
insertCodeBlock: (attrs) => {
|
25
|
+
return insertNode({ type: "codeBlock", attrs });
|
26
|
+
},
|
27
|
+
toggleCodeBlock: (attrs) => {
|
28
|
+
return toggleNode({ type: "codeBlock", attrs });
|
29
|
+
},
|
30
|
+
setCodeBlockAttrs: (attrs) => {
|
31
|
+
return setNodeAttrs({ type: "codeBlock", attrs });
|
32
|
+
}
|
25
33
|
});
|
26
34
|
}
|
27
35
|
|
@@ -53,24 +61,32 @@ function defineCodeBlockKeymap() {
|
|
53
61
|
});
|
54
62
|
}
|
55
63
|
var existCodeBlock = (state, dispatch) => {
|
56
|
-
if (!state.selection.empty)
|
57
|
-
return
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
64
|
+
if (!state.selection.empty) {
|
65
|
+
return false;
|
66
|
+
}
|
67
|
+
const { $head } = state.selection;
|
68
|
+
const parent = $head.parent;
|
69
|
+
if (parent.isTextblock && parent.type.spec.code && $head.parentOffset === parent.content.size && parent.textContent.endsWith("\n\n")) {
|
70
|
+
const grandParent = $head.node(-1);
|
71
|
+
const insertIndex = $head.indexAfter(-1);
|
72
|
+
const type = defaultBlockAt(grandParent.contentMatchAt(insertIndex));
|
73
|
+
if (!type || !grandParent.canReplaceWith(insertIndex, insertIndex, type)) {
|
74
|
+
return false;
|
75
|
+
}
|
65
76
|
if (dispatch) {
|
66
|
-
|
77
|
+
const { tr } = state;
|
67
78
|
tr.delete($head.pos - 2, $head.pos);
|
68
|
-
|
69
|
-
|
79
|
+
const pos = tr.selection.$head.after();
|
80
|
+
const node = type.createAndFill();
|
81
|
+
if (node) {
|
82
|
+
tr.replaceWith(pos, pos, node);
|
83
|
+
tr.setSelection(TextSelection.near(tr.doc.resolve(pos), 1));
|
84
|
+
dispatch(tr.scrollIntoView());
|
85
|
+
}
|
70
86
|
}
|
71
|
-
return
|
87
|
+
return true;
|
72
88
|
}
|
73
|
-
return
|
89
|
+
return false;
|
74
90
|
};
|
75
91
|
|
76
92
|
// src/code-block/code-block-spec.ts
|
@@ -80,8 +96,8 @@ function defineCodeBlockSpec() {
|
|
80
96
|
name: "codeBlock",
|
81
97
|
content: "text*",
|
82
98
|
group: "block",
|
83
|
-
code:
|
84
|
-
defining:
|
99
|
+
code: true,
|
100
|
+
defining: true,
|
85
101
|
marks: "",
|
86
102
|
attrs: { language: { default: "" } },
|
87
103
|
parseDOM: [
|
@@ -94,7 +110,8 @@ function defineCodeBlockSpec() {
|
|
94
110
|
}
|
95
111
|
],
|
96
112
|
toDOM(node) {
|
97
|
-
|
113
|
+
const attrs = node.attrs;
|
114
|
+
return ["pre", { "data-language": attrs.language }, ["code", 0]];
|
98
115
|
}
|
99
116
|
});
|
100
117
|
}
|
@@ -125,44 +142,63 @@ function defineCodeBlockHighlight({
|
|
125
142
|
import { createParser } from "prosemirror-highlight/shiki";
|
126
143
|
|
127
144
|
// src/code-block/shiki-highlighter.ts
|
128
|
-
var highlighter
|
145
|
+
var highlighter;
|
146
|
+
var loadedLangs = /* @__PURE__ */ new Set();
|
147
|
+
var loadedThemes = /* @__PURE__ */ new Set();
|
129
148
|
async function createHighlighter(options) {
|
130
|
-
|
131
|
-
|
149
|
+
const { getSingletonHighlighter } = await import("./shiki-import-UFUFVKJ2.js");
|
150
|
+
if (!highlighter) {
|
151
|
+
highlighter = await getSingletonHighlighter(options);
|
152
|
+
}
|
132
153
|
}
|
133
154
|
async function loadLanguages(langs) {
|
134
|
-
for (
|
155
|
+
for (const lang of langs) {
|
135
156
|
if (!highlighter) break;
|
136
|
-
await highlighter.loadLanguage(lang)
|
157
|
+
await highlighter.loadLanguage(lang);
|
158
|
+
loadedLangs.add(lang);
|
137
159
|
}
|
138
160
|
}
|
139
161
|
async function loadThemes(themes) {
|
140
|
-
for (
|
162
|
+
for (const theme of themes) {
|
141
163
|
if (!highlighter) break;
|
142
|
-
await highlighter.loadTheme(theme)
|
164
|
+
await highlighter.loadTheme(theme);
|
165
|
+
loadedThemes.add(theme);
|
143
166
|
}
|
144
167
|
}
|
145
168
|
function prepareHighlighter(options) {
|
146
|
-
if (!highlighter)
|
169
|
+
if (!highlighter) {
|
147
170
|
return { promise: createHighlighter(options) };
|
148
|
-
|
149
|
-
|
171
|
+
}
|
172
|
+
const langs = options.langs.filter((lang) => !loadedLangs.has(lang));
|
173
|
+
if (langs.length > 0) {
|
150
174
|
return { promise: loadLanguages(langs) };
|
151
|
-
|
152
|
-
|
175
|
+
}
|
176
|
+
const themes = options.themes.filter((theme) => !loadedThemes.has(theme));
|
177
|
+
if (themes.length > 0) {
|
178
|
+
return { promise: loadThemes(themes) };
|
179
|
+
}
|
180
|
+
return { highlighter };
|
153
181
|
}
|
154
182
|
|
155
183
|
// src/code-block/shiki-parser.ts
|
156
184
|
function createLazyParser(highlighterOptions) {
|
157
185
|
let parser;
|
158
|
-
|
159
|
-
|
186
|
+
prepareHighlighter(highlighterOptions);
|
187
|
+
return function lazyParser(options) {
|
188
|
+
const language = options.language || "";
|
189
|
+
const { highlighter: highlighter2, promise } = prepareHighlighter({
|
160
190
|
langs: [language],
|
161
191
|
themes: highlighterOptions.themes
|
162
192
|
});
|
163
|
-
|
164
|
-
|
165
|
-
}
|
193
|
+
if (!highlighter2) {
|
194
|
+
return promise;
|
195
|
+
}
|
196
|
+
if (!parser) {
|
197
|
+
parser = createParser(highlighter2, {
|
198
|
+
theme: highlighterOptions.themes[0]
|
199
|
+
});
|
200
|
+
}
|
201
|
+
return parser(options);
|
166
202
|
};
|
167
203
|
}
|
168
204
|
|
@@ -172,7 +208,7 @@ function defineCodeBlockShiki({
|
|
172
208
|
langs = ["text"],
|
173
209
|
langAlias = {}
|
174
210
|
} = {}) {
|
175
|
-
|
211
|
+
const parser = createLazyParser({ themes, langs, langAlias });
|
176
212
|
return defineCodeBlockHighlight({ parser });
|
177
213
|
}
|
178
214
|
|