Skip to content

Commit 5ee5ccb

Browse files
committed
fix(link): individual character links may be pasted repeatedly due to markdown parsing
1 parent 8015eab commit 5ee5ccb

File tree

3 files changed

+58
-9
lines changed

3 files changed

+58
-9
lines changed

Diff for: packages/engine/src/change/native-event.ts

+7-2
Original file line numberDiff line numberDiff line change
@@ -501,7 +501,12 @@ class NativeEvent {
501501
this.paste(source);
502502
const markdown = this.engine.options.markdown || {};
503503
if (markdown.mode !== false) {
504-
if (!markdown.check) {
504+
// 单独的链接不做解析,由 paste:each 触发执行
505+
if (
506+
!markdown.check &&
507+
text &&
508+
!/^https?:\/\/\S+$/i.test(text.trim())
509+
) {
505510
if (!text) return;
506511
// 没有 html,直接转换 markdown
507512
if (!html) {
@@ -579,7 +584,7 @@ class NativeEvent {
579584
pasteMarkdown(text);
580585
}, 0);
581586
}
582-
} else {
587+
} else if (markdown.check) {
583588
markdown
584589
.check(text ?? '', html ?? '')
585590
.then((result) => {

Diff for: plugins/link-vue/src/index.ts

+25-3
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ export default class<
4848
onConfirm: this.options.onConfirm,
4949
});
5050
this.editor.on('markdown-it', this.markdownIt);
51+
editor.on('paste:each', this.pasteHtml);
5152
}
5253
editor.on('parse:html', this.parseHtml);
5354
editor.on('select', this.bindQuery);
@@ -121,6 +122,25 @@ export default class<
121122
}
122123
};
123124

125+
pasteHtml = (child: NodeInterface) => {
126+
if (child.isText()) {
127+
const text = child.text();
128+
const { node, inline } = this.editor;
129+
if (
130+
/^https?:\/\/\S+$/.test(text.toLowerCase().trim()) &&
131+
inline.closest(child).equal(child)
132+
) {
133+
const newNode = node.wrap(
134+
child,
135+
$(`<${this.tagName} target="_blank" href="${text}"></a>`),
136+
);
137+
inline.repairCursor(newNode);
138+
return false;
139+
}
140+
}
141+
return true;
142+
};
143+
124144
parseHtml = (root: NodeInterface) => {
125145
root.find(this.tagName).css({
126146
'font-family': 'monospace',
@@ -136,8 +156,10 @@ export default class<
136156
};
137157

138158
destroy(): void {
139-
this.editor.off('parse:html', this.parseHtml);
140-
this.editor.off('select', this.bindQuery);
141-
this.editor.off('markdown-it', this.markdownIt);
159+
const editor = this.editor;
160+
editor.off('paste:each', this.pasteHtml);
161+
editor.off('parse:html', this.parseHtml);
162+
editor.off('select', this.bindQuery);
163+
editor.off('markdown-it', this.markdownIt);
142164
}
143165
}

Diff for: plugins/link/src/index.ts

+26-4
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@ export default class<
5151
this.toolbar = new Toolbar(editor, {
5252
onConfirm: this.options.onConfirm,
5353
});
54-
this.editor.on('markdown-it', this.markdownIt);
54+
editor.on('markdown-it', this.markdownIt);
55+
editor.on('paste:each', this.pasteHtml);
5556
}
5657
editor.on('parse:html', this.parseHtml);
5758
editor.on('select', this.bindQuery);
@@ -125,6 +126,25 @@ export default class<
125126
}
126127
};
127128

129+
pasteHtml = (child: NodeInterface) => {
130+
if (child.isText()) {
131+
const text = child.text();
132+
const { node, inline } = this.editor;
133+
if (
134+
/^https?:\/\/\S+$/.test(text.toLowerCase().trim()) &&
135+
inline.closest(child).equal(child)
136+
) {
137+
const newNode = node.wrap(
138+
child,
139+
$(`<${this.tagName} target="_blank" href="${text}"></a>`),
140+
);
141+
inline.repairCursor(newNode);
142+
return false;
143+
}
144+
}
145+
return true;
146+
};
147+
128148
parseHtml = (root: NodeInterface) => {
129149
root.find(this.tagName).css({
130150
'font-size': 'inherit',
@@ -136,8 +156,10 @@ export default class<
136156
};
137157

138158
destroy(): void {
139-
this.editor.off('parse:html', this.parseHtml);
140-
this.editor.off('select', this.bindQuery);
141-
this.editor.off('markdown-it', this.markdownIt);
159+
const editor = this.editor;
160+
editor.off('paste:each', this.pasteHtml);
161+
editor.off('parse:html', this.parseHtml);
162+
editor.off('select', this.bindQuery);
163+
editor.off('markdown-it', this.markdownIt);
142164
}
143165
}

0 commit comments

Comments
 (0)