Skip to content

Commit 585f45f

Browse files
committed
perf: build mention regex once in factory closure
1 parent 32934ec commit 585f45f

1 file changed

Lines changed: 15 additions & 19 deletions

File tree

src/lib/utils/marked/mention-extension.ts

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -18,24 +18,6 @@ function mentionStart(src: string) {
1818
return src.indexOf('<');
1919
}
2020

21-
function mentionTokenizer(this: any, src: string, options: MentionOptions = {}) {
22-
const trigger = options.triggerChar ?? '@';
23-
// Build dynamic regex for `<@id>`, `<@id|label>`, `<@id|>`
24-
// Added forward slash (/) to the character class for IDs
25-
const re = new RegExp(`^<\\${trigger}([\\w.\\-:/]+)(?:\\|([^>]*))?>`);
26-
const m = re.exec(src);
27-
if (!m) return;
28-
29-
const [, id, label] = m;
30-
return {
31-
type: 'mention',
32-
raw: m[0],
33-
triggerChar: trigger,
34-
id,
35-
label: label && label.length > 0 ? label : id
36-
};
37-
}
38-
3921
function mentionRenderer(token: any, options: MentionOptions = {}) {
4022
const trigger = options.triggerChar ?? '@';
4123
const cls = options.className ?? 'mention';
@@ -55,12 +37,26 @@ function mentionRenderer(token: any, options: MentionOptions = {}) {
5537
}
5638

5739
export function mentionExtension(opts: MentionOptions = {}) {
40+
// Compile the regex once when the extension is created, not on every tokenizer call.
41+
// mentionStart fires on every '<' in the document, making the tokenizer a hot path.
42+
const trigger = opts.triggerChar ?? '@';
43+
const re = new RegExp(`^<\\${trigger}([\\w.\\-:/]+)(?:\\|([^>]*))?>`);
44+
5845
return {
5946
name: 'mention',
6047
level: 'inline' as const,
6148
start: mentionStart,
6249
tokenizer(src: string) {
63-
return mentionTokenizer.call(this, src, opts);
50+
const m = re.exec(src);
51+
if (!m) return;
52+
const [, id, label] = m;
53+
return {
54+
type: 'mention',
55+
raw: m[0],
56+
triggerChar: trigger,
57+
id,
58+
label: label && label.length > 0 ? label : id
59+
};
6460
},
6561
renderer(token: any) {
6662
return mentionRenderer(token, opts);

0 commit comments

Comments
 (0)