這篇文章主要講解了“vscode中markdown預(yù)覽的實現(xiàn)原理”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“vscode中markdown預(yù)覽的實現(xiàn)原理”吧!
十余年建站經(jīng)驗, 網(wǎng)站制作、成都網(wǎng)站設(shè)計客戶的見證與正確選擇。創(chuàng)新互聯(lián)提供完善的營銷型網(wǎng)頁建站明細報價表。后期開發(fā)更加便捷高效,我們致力于追求更美、更快、更規(guī)范。
通過 vscode.window.createWebviewPanel 創(chuàng)建一個 webview,指定在側(cè)邊打開,之后通過該 panel 對象的 webview.html 屬性來設(shè)置 html。
html 是通過編輯器的 markdown 內(nèi)容生成的, 編輯器內(nèi)容通過 editor.document.getText() 拿到,然后調(diào)用第三方的 markdown 轉(zhuǎn) html 的庫來生成。
這樣就完成了 markdown 的預(yù)覽。
預(yù)覽之后需要更新,監(jiān)聽 vscode.workspace.onDidSaveTextDocument 和 vscode.workspace.onDidChangeTextDocument 的事件,在文檔更新和保存的時候,拿到編輯器的內(nèi)容,重新生成 html,然后設(shè)置到 webview。
webviewPanel 支持 webview.postMessage(message); 的方式傳遞消息,支持 updateHTML 等一系列 command,可以通過傳遞消息來觸發(fā)。
但是怎么知道哪個文檔更新哪個 webview 呢?
可以維護一個 map,在創(chuàng)建 webviewPanel 的時候記錄到 map 中,key 為文件路徑,這樣更新的時候就能查找到對應(yīng)的 webview 進行更新。
這樣,就完成了 markdown 內(nèi)容的更新。
其實整體思路還是比較簡單的,下面我們來寫下代碼
我們看下 vscode-markdown-preview-enhanced 的插件的代碼,這也是一個預(yù)覽 markdown 的插件,代碼還算簡潔,可以用來學(xué)習(xí)。
(以下代碼是簡化后的代碼)
首先,插件要指定觸發(fā)的條件,也就是在 package.json 里面指定 activationEvents:
"activationEvents": [ "onLanguage:markdown", "onCommand:markdown-preview-enhanced.openPreviewToTheSide" ],
這里一個是編輯 markdown 內(nèi)容的時候激活,一個是執(zhí)行 command 的時候激活。
具體激活的邏輯在 active 方法里:
export function activate(context: vscode.ExtensionContext) { const contentProvider = new MarkdownPreviewEnhancedView(context); context.subscriptions.push( vscode.commands.registerCommand( "markdown-preview-enhanced.openPreviewToTheSide", openPreviewToTheSide, ), ); function openPreviewToTheSide(uri?: vscode.Uri) { let resource = uri; if (!(resource instanceof vscode.Uri)) { if (vscode.window.activeTextEditor) { resource = vscode.window.activeTextEditor.document.uri; } } contentProvider.initPreview(resource, vscode.window.activeTextEditor, { viewColumn: vscode.ViewColumn.Two, preserveFocus: true, }); } }
我們注冊了那個 command,執(zhí)行 command 會拿到當(dāng)前 editor 的 url,然后進行 markdown 的 preview。
preview 的所有邏輯都集中定義在了 MarkdownPreviewEnhancedView 的實例對象中,在 command 觸發(fā)時執(zhí)行 initPreivew。
public async initPreview( sourceUri: vscode.Uri, editor: vscode.TextEditor, viewOptions: { viewColumn: vscode.ViewColumn; preserveFocus?: boolean }, ) { // 創(chuàng)建 webview let previewPanel: vscode.WebviewPanel = vscode.window.createWebviewPanel( "markdown-preview-enhanced", `Preview ${path.basename(sourceUri.fsPath)}`, viewOptions ); // 監(jiān)聽 webview 的消息 previewPanel.webview.onDidReceiveMessage((message) => {}); // 記錄 webview 到 map 中 this.previewMaps[sourceUri.fsPath] = previewPanel; // 拿到編輯器的文本,生成 html const text = editor.document.getText(); engine .generateHTMLTemplateForPreview({inputString: text}) .then((html) => { // 設(shè)置 html 到 previewPanel previewPanel.webview.html = html; }); }
在 initWebivew 里面創(chuàng)建 webviewPanel,同時把 webviewPanel 保存到 map 中,key 為文檔的文件路徑。拿到編輯器文本來生成 html,設(shè)置到 webview.html,這樣就完成了 markdown 的預(yù)覽。
這條路徑走通之后,我們就實現(xiàn)了 markdown 的預(yù)覽。
但是只預(yù)覽一次不行,更新文檔之后需要自動更新,我們繼續(xù)在 active 方法里添加事件監(jiān)聽:
context.subscriptions.push( vscode.workspace.onDidSaveTextDocument((document) => { if (isMarkdownFile(document)) { contentProvider.updateMarkdown(document.uri, true); } }), ); context.subscriptions.push( vscode.workspace.onDidChangeTextDocument((event) => { if (isMarkdownFile(event.document)) { contentProvider.update(event.document.uri); } }), );
監(jiān)聽文本修改和保存的時候,調(diào)用 update 方法來更新。
public updateMarkdown(sourceUri: Uri) { // 從 map 中根據(jù)文件路徑取出對應(yīng)的 webviewPanel const previewPanel = this.previewMaps[sourceUri.fsPath]; // 生成最新的 html 傳遞給 webview const text = document.getText(); engine .parseMD(text) .then(({ markdown, html }) => { previewPanel.webview.postMessage({ command: "updateHTML", html }); } }
這里是通過 webview.postMessage 給 html 內(nèi)容傳遞 updateHTML 的 command 消息,觸發(fā) html 內(nèi)容的更新。
這樣,我們就實現(xiàn)了 markdown 的同步刷新。
vscode 里面 markdown 的預(yù)覽是一個常用但實現(xiàn)起來并不難的功能,我們看了下 vscode-markdown-preview-enhanced 插件的源碼,理清了整體的流程:
通過 vscode.window.createWebviewPanel 創(chuàng)建 webviewPanel 來顯示 html
html 通過 editor.document.getText() 拿到文本內(nèi)容之后通過第三方包生成,設(shè)置到 webviewPanel
監(jiān)聽 workspace.onDidSaveTextDocument 和 workspace.onDidChangeTextDocument,來拿到最新內(nèi)容,之后生成 html 通過 webview.postMessage 傳遞 udpateHTML 的消息來更新到 webview。
要注意的是,需要記錄一個 map 來保存 uri.fsPath 和 webviewPanel 的對應(yīng)關(guān)系,實現(xiàn)文本內(nèi)容改變更新對應(yīng)的 webview
感謝各位的閱讀,以上就是“vscode中markdown預(yù)覽的實現(xiàn)原理”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對vscode中markdown預(yù)覽的實現(xiàn)原理這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關(guān)知識點的文章,歡迎關(guān)注!
文章名稱:vscode中markdown預(yù)覽的實現(xiàn)原理
文章轉(zhuǎn)載:http://chinadenli.net/article34/gphjse.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供、品牌網(wǎng)站制作、網(wǎng)站營銷、網(wǎng)站制作、App開發(fā)、域名注冊
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)