From 796b087131280f1a8962f5c99fde008809feefc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=98=BF=E8=8F=9C=20Cai?= Date: Fri, 11 Oct 2024 16:37:13 +0800 Subject: [PATCH] feat(vscodePlugin): open web link and open file link (#922) * feat(vscodePlugin): open web link and open file link * feat: open of local files * chore: remove `console.log` --- vscodePlugin/src/extension.ts | 26 ++++++++++++++++++ vscodePlugin/web-resources/scripts/index.js | 29 +++++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/vscodePlugin/src/extension.ts b/vscodePlugin/src/extension.ts index bb284b8a..002e03ff 100644 --- a/vscodePlugin/src/extension.ts +++ b/vscodePlugin/src/extension.ts @@ -195,6 +195,32 @@ const initCherryPanelEvent = () => { } }); break; + case 'open-url': { + if (data === 'href-invalid') { + vscode.window.showErrorMessage('link is not valid, please check it.'); + return; + } + // http/https协议的链接,直接打开 + if (/^(http|https):\/\//.test(data)) { + vscode.env.openExternal(vscode.Uri.parse(data)); + return; + } + // 本地绝对路径,打开文件(绝对路径需要解码) + const decodedData = decodeURIComponent(data); + if (path.isAbsolute(decodedData)) { + const decodedDataPath = vscode.Uri.file(decodedData); + vscode.commands.executeCommand('vscode.open', decodedDataPath, { preview: true }); + return; + } + // 以#开头的锚点不处理 + if (data.startsWith('#')) { + return; + } + // 本地相对路径,打开文件 + const uri = vscode.Uri.file(path.join(targetDocument.document.uri.fsPath, '..', data)); + vscode.commands.executeCommand('vscode.open', uri, { preview: true }); + break; + } } }); cherryPanel?.onDidDispose(() => { diff --git a/vscodePlugin/web-resources/scripts/index.js b/vscodePlugin/web-resources/scripts/index.js index c26f01e0..9f77d7a8 100644 --- a/vscodePlugin/web-resources/scripts/index.js +++ b/vscodePlugin/web-resources/scripts/index.js @@ -132,6 +132,22 @@ function changeTheme(theme) { )} theme__${theme}`; } +/** 处理 a 链接跳转问题 */ +const onClickLink = (target) => { + // 这里不能直接使用 target.href,因为本地相对文件地址会被vscode转成`webview://`协议 + const href = target.attributes?.href.value; + if (!href) { + vscode.postMessage({ + type: 'open-url', + data: 'href-invalid', + }); + }; + vscode.postMessage({ + type: 'open-url', + data: href, + }); +}; + const basicConfig = { id: 'markdown', externals: { @@ -307,6 +323,19 @@ const basicConfig = { src: path.join(basePath, srcValue), }; }, + onClickPreview: (e) => { + const { target } = e; + switch (target?.nodeName) { + case 'SPAN': + if (target?.parentElement?.nodeName === 'A') { + onClickLink(target?.parentElement); + } + break; + case 'A': + onClickLink(target); + break; + }; + }, }, };