private setupWebviewPanel()

in src/stepFunctions/commands/visualizeStateMachine/aslVisualization.ts [107:215]


    private setupWebviewPanel(textDocument: vscode.TextDocument): vscode.WebviewPanel {
        const documentUri = textDocument.uri
        const logger: Logger = getLogger()

        // Create and show panel
        const panel = this.createVisualizationWebviewPanel(documentUri)

        // Set the initial html for the webpage
        panel.webview.html = this.getWebviewContent(
            panel.webview.asWebviewUri(globals.visualizationResourcePaths.webviewBodyScript),
            panel.webview.asWebviewUri(globals.visualizationResourcePaths.visualizationLibraryScript),
            panel.webview.asWebviewUri(globals.visualizationResourcePaths.visualizationLibraryCSS),
            panel.webview.asWebviewUri(globals.visualizationResourcePaths.stateMachineCustomThemeCSS),
            panel.webview.cspSource,
            {
                inSync: localize(
                    'AWS.stepFunctions.graph.status.inSync',
                    'Previewing ASL document. <a href="" style="text-decoration:none;">View</a>'
                ),
                notInSync: localize('AWS.stepFunctions.graph.status.notInSync', 'Errors detected. Cannot preview.'),
                syncing: localize('AWS.stepFunctions.graph.status.syncing', 'Rendering ASL graph...'),
            }
        )

        // Add listener function to update the graph on document save
        this.disposables.push(
            vscode.workspace.onDidSaveTextDocument(async savedTextDocument => {
                if (savedTextDocument && savedTextDocument.uri.path === documentUri.path) {
                    await this.sendUpdateMessage(savedTextDocument)
                }
            })
        )

        // If documentUri being tracked is no longer found (due to file closure or rename), close the panel.
        this.disposables.push(
            vscode.workspace.onDidCloseTextDocument(documentWillSaveEvent => {
                if (!this.trackedDocumentDoesExist(documentUri) && !this.isPanelDisposed) {
                    panel.dispose()
                    vscode.window.showInformationMessage(
                        localize(
                            'AWS.stepfunctions.visualisation.errors.rename',
                            'State machine visualization closed due to file renaming or closure.'
                        )
                    )
                }
            })
        )

        const debouncedUpdate = debounce(this.sendUpdateMessage.bind(this), 500)

        this.disposables.push(
            vscode.workspace.onDidChangeTextDocument(async textDocumentEvent => {
                if (textDocumentEvent.document.uri.path === documentUri.path) {
                    await debouncedUpdate(textDocumentEvent.document)
                }
            })
        )

        // Handle messages from the webview
        this.disposables.push(
            panel.webview.onDidReceiveMessage(async (message: MessageObject) => {
                switch (message.command) {
                    case 'updateResult':
                        logger.debug(message.text)
                        if (message.error) {
                            logger.error(message.error)
                        }
                        break
                    case 'webviewRendered': {
                        // Webview has finished rendering, so now we can give it our
                        // initial state machine definition.
                        await this.sendUpdateMessage(textDocument)
                        break
                    }

                    case 'viewDocument':
                        try {
                            const document = await vscode.workspace.openTextDocument(documentUri)
                            vscode.window.showTextDocument(document, vscode.ViewColumn.One)
                        } catch (e) {
                            logger.error(e as Error)
                        }
                        break
                }
            })
        )

        // When the panel is closed, dispose of any disposables/remove subscriptions
        const disposePanel = () => {
            if (this.isPanelDisposed) {
                return
            }
            this.isPanelDisposed = true
            debouncedUpdate.cancel()
            this.onVisualizationDisposeEmitter.fire()
            this.disposables.forEach(disposable => {
                disposable.dispose()
            })
            this.onVisualizationDisposeEmitter.dispose()
        }

        this.disposables.push(
            panel.onDidDispose(() => {
                disposePanel()
            })
        )

        return panel
    }