Allow the extension tab to refresh test images in background (#4689)

This commit is contained in:
Leedehai 2024-08-11 16:37:18 -04:00 committed by GitHub
parent 79fb2c3689
commit 54a1a7492f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -11,13 +11,15 @@ export function activate(context: vscode.ExtensionContext) {
export function deactivate() {} export function deactivate() {}
class TestHelper { class TestHelper {
// The currently active view for a test or `null` if none. // The opened tab for a test or `undefined` if none. A non-empty "opened"
active?: { // means there is a TestHelper editor tab present, but the content within
// that tab (i.e. the WebView panel) might not be visible yet.
opened?: {
// The tests's name. // The tests's name.
name: string; name: string;
// The WebView panel that displays the test images and output. // The WebView panel that displays the test images and output.
panel: vscode.WebviewPanel; panel: vscode.WebviewPanel;
} | null; };
// The current zoom scale. // The current zoom scale.
scale = 1.0; scale = 1.0;
@ -33,8 +35,6 @@ class TestHelper {
// Sets the extension up. // Sets the extension up.
constructor(private readonly context: vscode.ExtensionContext) { constructor(private readonly context: vscode.ExtensionContext) {
this.active = null;
// Code lens that displays commands inline with the tests. // Code lens that displays commands inline with the tests.
this.context.subscriptions.push( this.context.subscriptions.push(
vscode.languages.registerCodeLensProvider( vscode.languages.registerCodeLensProvider(
@ -160,14 +160,14 @@ class TestHelper {
// Triggered when clicking "View" in the lens. // Triggered when clicking "View" in the lens.
private viewFromLens(name: string) { private viewFromLens(name: string) {
if (this.active) { if (this.opened?.name == name) {
if (this.active.name == name) { this.opened.panel.reveal();
this.active.panel.reveal(); return;
return; }
}
this.active.name = name; if (this.opened) {
this.active.panel.title = name; this.opened.name = name;
this.opened.panel.title = name;
} else { } else {
const panel = vscode.window.createWebviewPanel( const panel = vscode.window.createWebviewPanel(
"typst-test-helper.preview", "typst-test-helper.preview",
@ -176,9 +176,9 @@ class TestHelper {
{ enableFindWidget: true } { enableFindWidget: true }
); );
panel.onDidDispose(() => (this.active = null)); panel.onDidDispose(() => (this.opened = undefined));
this.active = { name, panel }; this.opened = { name, panel };
} }
this.refreshWebView(); this.refreshWebView();
@ -211,23 +211,23 @@ class TestHelper {
// Triggered when clicking the "Refresh" button in the WebView toolbar. // Triggered when clicking the "Refresh" button in the WebView toolbar.
private refreshFromPreview() { private refreshFromPreview() {
if (this.active) { if (this.opened) {
this.active.panel.reveal(); this.opened.panel.reveal();
this.refreshWebView(); this.refreshWebView();
} }
} }
// Triggered when clicking the "Run" button in the WebView toolbar. // Triggered when clicking the "Run" button in the WebView toolbar.
private runFromPreview() { private runFromPreview() {
if (this.active) { if (this.opened) {
this.runCargoTest(this.active.name); this.runCargoTest(this.opened.name);
} }
} }
// Triggered when clicking the "Save" button in the WebView toolbar. // Triggered when clicking the "Save" button in the WebView toolbar.
private saveFromPreview() { private saveFromPreview() {
if (this.active) { if (this.opened) {
this.runCargoTest(this.active.name, true); this.runCargoTest(this.opened.name, true);
} }
} }
@ -286,8 +286,8 @@ class TestHelper {
// Triggered when performing a right-click on an image in the WebView. // Triggered when performing a right-click on an image in the WebView.
private copyImageFilePathFromPreviewContext(webviewSection: string) { private copyImageFilePathFromPreviewContext(webviewSection: string) {
if (!this.active) return; if (!this.opened) return;
const { name } = this.active; const { name } = this.opened;
const { png, ref } = getImageUris(name); const { png, ref } = getImageUris(name);
switch (webviewSection) { switch (webviewSection) {
case "png": case "png":
@ -303,13 +303,14 @@ class TestHelper {
// Reloads the web view. // Reloads the web view.
private refreshWebView(output?: { stdout: string; stderr: string }) { private refreshWebView(output?: { stdout: string; stderr: string }) {
if (!this.active) return; if (!this.opened) return;
const { name, panel } = this.active; const { name, panel } = this.opened;
const { png, ref } = getImageUris(name); const { png, ref } = getImageUris(name);
if (panel && panel.visible) { if (panel) {
console.log(`Refreshing WebView for ${name}`); console.log(
`Refreshing WebView for ${name}` + (panel.visible ? " in background" : ""));
const webViewSrcs = { const webViewSrcs = {
png: panel.webview.asWebviewUri(png), png: panel.webview.asWebviewUri(png),
ref: panel.webview.asWebviewUri(ref), ref: panel.webview.asWebviewUri(ref),
@ -403,6 +404,14 @@ function getWebviewContent(
): string { ): string {
const escape = (text: string) => const escape = (text: string) =>
text.replace(/</g, "&lt;").replace(/>/g, "&gt;"); text.replace(/</g, "&lt;").replace(/>/g, "&gt;");
const stdoutHtml = output?.stdout
? `<h1>Standard output</h1><pre>${escape(output.stdout)}</pre>`
: "";
const stderrHtml = output?.stderr
? `<h1>Standard error</h1><pre>${escape(output.stderr)}</pre>`
: "";
return ` return `
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
@ -478,16 +487,8 @@ function getWebviewContent(
/> />
</div> </div>
</div> </div>
${ ${stdoutHtml}
output?.stdout ${stderrHtml}
? `<h1>Standard output</h1><pre>${escape(output.stdout)}</pre>`
: ""
}
${
output?.stderr
? `<h1>Standard error</h1><pre>${escape(output.stderr)}</pre>`
: ""
}
</body> </body>
</html>`; </html>`;
} }