Path: blob/main/extensions/media-preview/src/audioPreview.ts
4772 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import * as vscode from 'vscode';6import { BinarySizeStatusBarEntry } from './binarySizeStatusBarEntry';7import { MediaPreview, reopenAsText } from './mediaPreview';8import { escapeAttribute } from './util/dom';9import { generateUuid } from './util/uuid';1011class AudioPreviewProvider implements vscode.CustomReadonlyEditorProvider {1213public static readonly viewType = 'vscode.audioPreview';1415constructor(16private readonly extensionRoot: vscode.Uri,17private readonly binarySizeStatusBarEntry: BinarySizeStatusBarEntry,18) { }1920public async openCustomDocument(uri: vscode.Uri) {21return { uri, dispose: () => { } };22}2324public async resolveCustomEditor(document: vscode.CustomDocument, webviewEditor: vscode.WebviewPanel): Promise<void> {25new AudioPreview(this.extensionRoot, document.uri, webviewEditor, this.binarySizeStatusBarEntry);26}27}282930class AudioPreview extends MediaPreview {3132constructor(33private readonly extensionRoot: vscode.Uri,34resource: vscode.Uri,35webviewEditor: vscode.WebviewPanel,36binarySizeStatusBarEntry: BinarySizeStatusBarEntry,37) {38super(extensionRoot, resource, webviewEditor, binarySizeStatusBarEntry);3940this._register(webviewEditor.webview.onDidReceiveMessage(message => {41switch (message.type) {42case 'reopen-as-text': {43reopenAsText(resource, webviewEditor.viewColumn);44break;45}46}47}));4849this.updateBinarySize();50this.render();51this.updateState();52}5354protected async getWebviewContents(): Promise<string> {55const version = Date.now().toString();56const settings = {57src: await this.getResourcePath(this._webviewEditor, this._resource, version),58};5960const nonce = generateUuid();6162const cspSource = this._webviewEditor.webview.cspSource;63return /* html */`<!DOCTYPE html>64<html lang="en">65<head>66<meta charset="UTF-8">6768<!-- Disable pinch zooming -->69<meta name="viewport"70content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no">7172<title>Audio Preview</title>7374<link rel="stylesheet" href="${escapeAttribute(this.extensionResource('media', 'audioPreview.css'))}" type="text/css" media="screen" nonce="${nonce}">7576<meta http-equiv="Content-Security-Policy" content="default-src 'none'; img-src data: ${cspSource}; media-src ${cspSource}; script-src 'nonce-${nonce}'; style-src ${cspSource} 'nonce-${nonce}';">77<meta id="settings" data-settings="${escapeAttribute(JSON.stringify(settings))}">78</head>79<body class="container loading" data-vscode-context='{ "preventDefaultContextMenuItems": true }'>80<div class="loading-indicator"></div>81<div class="loading-error">82<p>${vscode.l10n.t("An error occurred while loading the audio file.")}</p>83<a href="#" class="open-file-link">${vscode.l10n.t("Open file using VS Code's standard text/binary editor?")}</a>84</div>85<script src="${escapeAttribute(this.extensionResource('media', 'audioPreview.js'))}" nonce="${nonce}"></script>86</body>87</html>`;88}8990private async getResourcePath(webviewEditor: vscode.WebviewPanel, resource: vscode.Uri, version: string): Promise<string | null> {91if (resource.scheme === 'git') {92const stat = await vscode.workspace.fs.stat(resource);93if (stat.size === 0) {94// The file is stored on git lfs95return null;96}97}9899// Avoid adding cache busting if there is already a query string100if (resource.query) {101return webviewEditor.webview.asWebviewUri(resource).toString();102}103return webviewEditor.webview.asWebviewUri(resource).with({ query: `version=${version}` }).toString();104}105106private extensionResource(...parts: string[]) {107return this._webviewEditor.webview.asWebviewUri(vscode.Uri.joinPath(this.extensionRoot, ...parts));108}109}110111export function registerAudioPreviewSupport(context: vscode.ExtensionContext, binarySizeStatusBarEntry: BinarySizeStatusBarEntry): vscode.Disposable {112const provider = new AudioPreviewProvider(context.extensionUri, binarySizeStatusBarEntry);113return vscode.window.registerCustomEditorProvider(AudioPreviewProvider.viewType, provider, {114supportsMultipleEditorsPerDocument: true,115webviewOptions: {116retainContextWhenHidden: true,117}118});119}120121122