vscode插件开发,使用CustomEditor进行OFD文件预览
使用js开发,对ofd预览使用的三方库是 ofd.js
,通过将 ofd.js
继承到插件里面对点击ofd文件进行预览的效果
要实现的效果大致如下:
- 识别*.ofd结尾的文件
- 打开OfdViewer窗口,实现预览ofd文件
那么开始了,这里就不详细讲解如何创建vscode插件开发,直接看几个重要的代码,也就是实现的逻辑。
首先注册自定义预览窗口,这里定义了一个OFD Viewer
的 CustomEditor ,实现一个webview来进行预览操作,他只对ofd
结尾的文件有效
"contributes": {
"customEditors": [
{
"viewType": "com.xxss0903.ofdviewer",
"displayName": "OFD Viewer",
"selector": [
{
"filenamePattern": "*.ofd"
}
]
}
],
},
有了上面的注册我们再src文件夹下面创建一个ofdEditor.ts文件,这个是OFD Viewer
的插件入口,用于插件的一般操作以及与webview进行互动。
有了ofdEditor
之后我们需要在extensions里对预览插件进行注册
完成上面几步就创建了一个基本的插件了,接下来就是对插件进行功能开发了。
首先是获取一个webview对应的html内容,webview将加载下面部分的html文件,可以看到引用了media文件夹下面的ofdViewer.js和ofdviewer.css
两个前端需要的js和css文件。并且我们也把ofd的打包文件ofd.umd.js
放到了media文件夹下面用于加载ofd.js插件。
private getHtmlForWebview(webview: vscode.Webview): string {
// Local path to script and css for the webview
const scriptUri = webview.asWebviewUri(
vscode.Uri.joinPath(this._context.extensionUri, "media", "ofdViewer.js")
);
const scriptOfdUri = webview.asWebviewUri(
vscode.Uri.joinPath(this._context.extensionUri, "media", "ofd.umd.js")
);
const scriptUri3 = webview.asWebviewUri(
vscode.Uri.joinPath(this._context.extensionUri, "media", "ofdViewerVue.js")
);
const styleResetUri = webview.asWebviewUri(
vscode.Uri.joinPath(this._context.extensionUri, "media", "reset.css")
);
const styleVSCodeUri = webview.asWebviewUri(
vscode.Uri.joinPath(this._context.extensionUri, "media", "vscode.css")
);
const styleMainUri = webview.asWebviewUri(
vscode.Uri.joinPath(this._context.extensionUri, "media", "ofdViewer.css")
);
// Use a nonce to whitelist which scripts can be run
const nonce = getNonce();
const nonce2 = getNonce();
console.log("get nonce", nonce, nonce2);
return /* html */ `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<!--
Use a content security policy to only allow loading images from https or from our extension directory,
and only allow scripts that have a specific nonce.
-->
<meta http-equiv="Content-Security-Policy" content="default-src * 'self' 'unsafe-inline' 'unsafe-eval' data: gap: content: https://xxx.com;media-src * blob: 'self' http://* 'unsafe-inline' 'unsafe-eval';style-src * 'self' 'unsafe-inline';img-src * 'self' data: content:;connect-src * blob:;">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="${styleResetUri}" rel="stylesheet" />
<link href="${styleVSCodeUri}" rel="stylesheet" />
<link href="${styleMainUri}" rel="stylesheet" />
<title>Paw Draw</title>
<script src="https://cdn.staticfile.org/vue/3.2.36/vue.global.min.js"></script>
</head>
<body>
<div id="app">
<div ref="ofdContainerRef" id="ofd-container"></div>
<div display="gone" ref="ofdDataRef" id="ofd-data">
<textarea ref="codeMirrorRef" id="code-mirror"></textarea>
</div>
</div>
<script type="module" src="${scriptOfdUri}"></script>
<script type="module" src="${scriptUri}"></script>
<script type="module" src="${scriptUri3}"></script>
</body>
</html>`;
}
接下来就是ofdViewer.js的内容,用于解析和预览ofd文件了
(function () {
const vscode = acquireVsCodeApi();
const screenWidth = document.body.clientWidth;
function displayOfdElementToPage(views) {
let ofdContainer = document.querySelector(".ofd-container");
ofdContainer.innerHTML = "";
for (const div of views) {
ofdContainer.appendChild(div);
}
}
window.addEventListener("message", async (e) => {
const { type, body, requestId } = e.data;
// console.log("ofdeditor listen message", e.data);
switch (type) {
case "init":
// console.log("ofeditor html init");
case "update":
// console.log("ofeditor html update");
case "getFileData":
// console.log("ofeditor html getFileData", body);
// var abBody = body.value.buffer;
ofd.parseOfdDocument({
ofd: body.value,
success(res) {
// console.log("ofdeditor success", res);
// 渲染ofd
const ofdView = ofd.renderOfd(screenWidth, res[0]);
//将ofd添加到html上面
displayOfdElementToPage(ofdView);
},
fail(error) {
// console.log("ofdeditor parse error", error);
vscode.postMessage({
type: 'openOfdError',
error: error.message
});
},
});
}
});
// Signal to VS Code that the webview is initialized.
// 先通知vs插件js代码准备好了,然后vscode插件会返回init方法来通知js进行自己的初始化
vscode.postMessage({ type: "ready" });
})();
主要是添加了一个window.addEventListener的方法,用于插件和webview进行通信,比如插件点击文件之后传输文件路径给webview,webview将解析错误发生时传输错误给插件用于消息提示。
所有的源码地址
打包vsix的包,然后发布
使用vsce
进行打包,在项目根目录安装 npm install -g @vscode/vsce
,然后再执行命令vsce package
,此时会打包成一个***-0.0.3.vsix
的vsix插件包文件,然后接着可以进行发布了。
发布参考官方文档