fix(tiptap): correct link command order + validate URL scheme in slash commands

This commit is contained in:
xfy 2026-06-23 18:42:57 +08:00
parent e580c3ab18
commit 6ffcd55c94

View File

@ -167,7 +167,7 @@ export const SlashCommand = Extension.create<SlashCommandOptions>({
icon: '🖼',
command: ({ editor, range }) => {
const url = window.prompt('输入图片 URL')
if (url) {
if (url && isValidUrl(url)) {
editor.chain().focus().deleteRange(range).setImage({ src: url }).run()
}
},
@ -178,9 +178,17 @@ export const SlashCommand = Extension.create<SlashCommandOptions>({
icon: '🔗',
command: ({ editor, range }) => {
const url = window.prompt('输入链接 URL')
if (url) {
editor.chain().focus().deleteRange(range).setLink({ href: url }).insertContent(url).run()
}
if (!url || !isValidUrl(url)) return
// deleteRange 后光标停在 range.to先插入 URL 文本,再选中刚插入的范围设 link
// setLink 需要非空选区才生效,原顺序 setLink 在空选区无效)。
const insertFrom = range.to
editor.chain()
.focus()
.deleteRange(range)
.insertContent(url)
.setTextSelection({ from: insertFrom, to: insertFrom + url.length })
.setLink({ href: url })
.run()
},
},
)
@ -238,6 +246,11 @@ interface SlashPopup {
destroy(): void
}
/** 校验图片/链接 URL:只允许 http(s) 和 data:image。拒绝 javascript: 等。 */
function isValidUrl(url: string): boolean {
return /^https?:\/\//i.test(url) || /^data:image\//i.test(url)
}
function createPopup(props: SuggestionProps<CommandItem>): SlashPopup {
const component = document.createElement('div')
component.classList.add('slash-command')