简体   繁体   English

VSCode 扩展:自定义编辑器 Webview 都在 typescript

[英]VSCode extension: Custom Editor with Webview both on typescript

I need to create VSCode extension.我需要创建 VSCode 扩展。 There should be Custom Editor with Webview. Also I need to use shared code in Custom Editor and Webview. Plus I need to use some libs so I plan to use webpack. yo code can generate extension skeleton with typescript and webpack. But I can't generate file for Webview.应该有带有 Webview 的自定义编辑器。我还需要在自定义编辑器和 Webview 中使用共享代码。另外,我需要使用一些库,所以我打算使用 webpack。你的yo code可以生成带有 typescript 和 webpack 的扩展框架。但我不能t 为 Webview 生成文件。

First create a production build with webpack. This serves as the content for your webview. But because it is not possible to load the webview from an URL directly, you have to insert an iframe and load that from the URL instead.首先使用 webpack 创建一个生产版本。这作为您的 webview 的内容。但是因为无法直接从 URL 加载 webview,所以您必须插入 iframe 并从 88165788660208 加载它

    protected createPanel(caption: string, url: URL, placement?: string): Promise<boolean> {
        return new Promise((resolve) => {
            const viewColumn = (!placement || placement === "Active") ? ViewColumn.Active : ViewColumn.Beside;
            if (placement === "Beside Bottom") {
                void commands.executeCommand("workbench.action.editorLayoutTwoRows");
            }

            this.panel = window.createWebviewPanel(
                "the-webview", caption, viewColumn, {
                    enableScripts: true,
                    retainContextWhenHidden: true,
                },
            );

            this.panel.onDidDispose(() => { this.handleDispose(); });

            this.panel.webview.onDidReceiveMessage((message: IEmbeddedMessage) => {
                if (message.source === "app") {
                    // Handle webview messages here.
                }
            });

            // Insert an iframe to load the external URL.
            this.panel.webview.html = `
    <!doctype html><html lang="en">
    <head>
    <meta http-equiv="Content-Security-Policy" content="default-src *; img-src http: https:;
        script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'unsafe-inline' http: https: data: *;">
    </head>
    <body style="margin:0px;padding:0px;overflow:hidden;">
    <iframe id="frame:${caption}"
        src="${url.toString()}"
        frameborder="0" style="overflow: hidden; overflow-x: hidden; overflow-y: hidden; height:100%;
        width:100%; position: absolute; top: 0px; left: 0px; right: 0px; bottom: 0px" height="100%"
        width="100%">
    </iframe>
    <script>
        let frame;
        let vscode;

        window.addEventListener('message', (event) => {
            if (!frame) {
                vscode = acquireVsCodeApi();
                frame = document.getElementById("frame:${caption}");
            }

            if (event.data.source === "host") {
                // Forward message from the extension to the iframe.
                frame.contentWindow.postMessage(event.data, "*");
            } else if (event.data.source === "app") {
                // Forward messages from the iframe to the extension.
                vscode.postMessage(event.data);
            } else {
                // Forward certain messages to our parent window, which will further forward to vscode.
                switch (event.data.type) {
                    case "keydown": {
                        window.dispatchEvent(new KeyboardEvent("keydown", event.data));
                        break;
                    }
                    case "keyup": {
                        window.dispatchEvent(new KeyboardEvent("keyup", event.data));
                        break;
                    }
                }
            }
        });
    </script>

    </body></html>
    `;

        });
    }

The webview itself is also an iframe, but message handling between that and vscode is already in place. webview 本身也是一个 iframe,但是它和 vscode 之间的消息处理已经到位。 However for that additional iframe you have to do something similar to forward message either from your app code to vscode or the other direction.但是,对于额外的 iframe,您必须执行类似于将消息从您的应用程序代码转发到 vscode 或其他方向的操作。 In my code I use a field in the sent data to decide which direction I have to take.在我的代码中,我使用发送数据中的一个字段来决定我必须采取的方向。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM