Make webview panel creation async
This will make the creation of a webview panel async to allow the `getPanelConfig` method to be an async function. This will allow us to do some work (like retrieving the variant analysis) in the `getPanelConfig` method.
This commit is contained in:
@@ -5,7 +5,7 @@ import {
|
||||
ViewColumn,
|
||||
Uri,
|
||||
WebviewPanelOptions,
|
||||
WebviewOptions
|
||||
WebviewOptions,
|
||||
} from 'vscode';
|
||||
import * as path from 'path';
|
||||
|
||||
@@ -27,6 +27,8 @@ export abstract class AbstractWebview<ToMessage extends WebviewMessage, FromMess
|
||||
protected panelLoaded = false;
|
||||
protected panelLoadedCallBacks: (() => void)[] = [];
|
||||
|
||||
private panelResolves?: Array<(panel: WebviewPanel) => void>;
|
||||
|
||||
constructor(
|
||||
protected readonly ctx: ExtensionContext
|
||||
) {
|
||||
@@ -35,20 +37,36 @@ export abstract class AbstractWebview<ToMessage extends WebviewMessage, FromMess
|
||||
|
||||
public async restoreView(panel: WebviewPanel): Promise<void> {
|
||||
this.panel = panel;
|
||||
this.setupPanel(panel);
|
||||
const config = await this.getPanelConfig();
|
||||
await this.setupPanel(panel, config);
|
||||
}
|
||||
|
||||
protected get isShowingPanel() {
|
||||
return !!this.panel;
|
||||
}
|
||||
|
||||
protected getPanel(): WebviewPanel {
|
||||
protected async getPanel(): Promise<WebviewPanel> {
|
||||
if (this.panel == undefined) {
|
||||
const { ctx } = this;
|
||||
|
||||
const config = this.getPanelConfig();
|
||||
// This is an async method, so in theory this method can be called concurrently. To ensure that we don't
|
||||
// create two panels, we use a promise that resolves when the panel is created. This way, if the panel is
|
||||
// being created, the promise will resolve when it is done.
|
||||
if (this.panelResolves !== undefined) {
|
||||
return new Promise((resolve) => {
|
||||
if (this.panel !== undefined) {
|
||||
resolve(this.panel);
|
||||
return;
|
||||
}
|
||||
|
||||
this.panel = Window.createWebviewPanel(
|
||||
this.panelResolves?.push(resolve);
|
||||
});
|
||||
}
|
||||
this.panelResolves = [];
|
||||
|
||||
const config = await this.getPanelConfig();
|
||||
|
||||
const panel = Window.createWebviewPanel(
|
||||
config.viewId,
|
||||
config.title,
|
||||
{ viewColumn: config.viewColumn, preserveFocus: config.preserveFocus },
|
||||
@@ -64,14 +82,17 @@ export abstract class AbstractWebview<ToMessage extends WebviewMessage, FromMess
|
||||
],
|
||||
}
|
||||
);
|
||||
this.setupPanel(this.panel);
|
||||
this.panel = panel;
|
||||
|
||||
this.setupPanel(panel, config);
|
||||
|
||||
this.panelResolves.forEach((resolve) => resolve(panel));
|
||||
this.panelResolves = undefined;
|
||||
}
|
||||
return this.panel;
|
||||
}
|
||||
|
||||
protected setupPanel(panel: WebviewPanel): void {
|
||||
const config = this.getPanelConfig();
|
||||
|
||||
protected setupPanel(panel: WebviewPanel, config: WebviewPanelConfig): void {
|
||||
this.push(
|
||||
panel.onDidDispose(
|
||||
() => {
|
||||
@@ -101,7 +122,7 @@ export abstract class AbstractWebview<ToMessage extends WebviewMessage, FromMess
|
||||
);
|
||||
}
|
||||
|
||||
protected abstract getPanelConfig(): WebviewPanelConfig;
|
||||
protected abstract getPanelConfig(): WebviewPanelConfig | Promise<WebviewPanelConfig>;
|
||||
|
||||
protected abstract onPanelDispose(): void;
|
||||
|
||||
@@ -123,7 +144,8 @@ export abstract class AbstractWebview<ToMessage extends WebviewMessage, FromMess
|
||||
this.panelLoadedCallBacks = [];
|
||||
}
|
||||
|
||||
protected postMessage(msg: ToMessage): Thenable<boolean> {
|
||||
return this.getPanel().webview.postMessage(msg);
|
||||
protected async postMessage(msg: ToMessage): Promise<boolean> {
|
||||
const panel = await this.getPanel();
|
||||
return panel.webview.postMessage(msg);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,7 +46,8 @@ export class CompareView extends AbstractWebview<ToCompareViewMessage, FromCompa
|
||||
selectedResultSetName?: string
|
||||
) {
|
||||
this.comparePair = { from, to };
|
||||
this.getPanel().reveal(undefined, true);
|
||||
const panel = await this.getPanel();
|
||||
panel.reveal(undefined, true);
|
||||
|
||||
await this.waitForPanelLoaded();
|
||||
const [
|
||||
|
||||
@@ -7,7 +7,7 @@ import {
|
||||
languages,
|
||||
Uri,
|
||||
window as Window,
|
||||
env
|
||||
env, WebviewPanel
|
||||
} from 'vscode';
|
||||
import * as cli from './cli';
|
||||
import { CodeQLCliServer } from './cli';
|
||||
@@ -341,6 +341,8 @@ export class ResultsView extends AbstractWebview<IntoResultsViewMsg, FromResults
|
||||
return;
|
||||
}
|
||||
|
||||
const panel = await this.getPanel();
|
||||
|
||||
this._interpretation = undefined;
|
||||
const interpretationPage = await this.interpretResultsInfo(
|
||||
fullQuery.completedQuery.query,
|
||||
@@ -350,12 +352,11 @@ export class ResultsView extends AbstractWebview<IntoResultsViewMsg, FromResults
|
||||
const sortedResultsMap: SortedResultsMap = {};
|
||||
Object.entries(fullQuery.completedQuery.sortedResultsInfo).forEach(
|
||||
([k, v]) =>
|
||||
(sortedResultsMap[k] = this.convertPathPropertiesToWebviewUris(v))
|
||||
(sortedResultsMap[k] = this.convertPathPropertiesToWebviewUris(panel, v))
|
||||
);
|
||||
|
||||
this._displayedQuery = fullQuery;
|
||||
|
||||
const panel = this.getPanel();
|
||||
await this.waitForPanelLoaded();
|
||||
if (!panel.visible) {
|
||||
if (forceReveal === WebviewReveal.Forced) {
|
||||
@@ -426,6 +427,7 @@ export class ResultsView extends AbstractWebview<IntoResultsViewMsg, FromResults
|
||||
interpretation: interpretationPage,
|
||||
origResultsPaths: fullQuery.completedQuery.query.resultsPaths,
|
||||
resultsPath: this.convertPathToWebviewUri(
|
||||
panel,
|
||||
fullQuery.completedQuery.query.resultsPaths.resultsPath
|
||||
),
|
||||
parsedResultSets,
|
||||
@@ -498,10 +500,12 @@ export class ResultsView extends AbstractWebview<IntoResultsViewMsg, FromResults
|
||||
throw new Error('trying to view a page of a query that is not loaded');
|
||||
}
|
||||
|
||||
const panel = await this.getPanel();
|
||||
|
||||
const sortedResultsMap: SortedResultsMap = {};
|
||||
Object.entries(results.completedQuery.sortedResultsInfo).forEach(
|
||||
([k, v]) =>
|
||||
(sortedResultsMap[k] = this.convertPathPropertiesToWebviewUris(v))
|
||||
(sortedResultsMap[k] = this.convertPathPropertiesToWebviewUris(panel, v))
|
||||
);
|
||||
|
||||
const resultSetSchemas = await this.getResultSetSchemas(results.completedQuery, sorted ? selectedTable : '');
|
||||
@@ -544,6 +548,7 @@ export class ResultsView extends AbstractWebview<IntoResultsViewMsg, FromResults
|
||||
interpretation: this._interpretation,
|
||||
origResultsPaths: results.completedQuery.query.resultsPaths,
|
||||
resultsPath: this.convertPathToWebviewUri(
|
||||
panel,
|
||||
results.completedQuery.query.resultsPaths.resultsPath
|
||||
),
|
||||
parsedResultSets,
|
||||
@@ -812,15 +817,16 @@ export class ResultsView extends AbstractWebview<IntoResultsViewMsg, FromResults
|
||||
this._diagnosticCollection.set(diagnostics);
|
||||
}
|
||||
|
||||
private convertPathToWebviewUri(path: string): string {
|
||||
return fileUriToWebviewUri(this.getPanel(), Uri.file(path));
|
||||
private convertPathToWebviewUri(panel: WebviewPanel, path: string): string {
|
||||
return fileUriToWebviewUri(panel, Uri.file(path));
|
||||
}
|
||||
|
||||
private convertPathPropertiesToWebviewUris(
|
||||
panel: WebviewPanel,
|
||||
info: SortedResultSetInfo
|
||||
): SortedResultSetInfo {
|
||||
return {
|
||||
resultsPath: this.convertPathToWebviewUri(info.resultsPath),
|
||||
resultsPath: this.convertPathToWebviewUri(panel, info.resultsPath),
|
||||
sortState: info.sortState,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -49,7 +49,8 @@ export class RemoteQueriesView extends AbstractWebview<ToRemoteQueriesMessage, F
|
||||
}
|
||||
|
||||
async showResults(query: RemoteQuery, queryResult: RemoteQueryResult) {
|
||||
this.getPanel().reveal(undefined, true);
|
||||
const panel = await this.getPanel();
|
||||
panel.reveal(undefined, true);
|
||||
|
||||
await this.waitForPanelLoaded();
|
||||
const model = this.buildViewModel(query, queryResult);
|
||||
|
||||
@@ -26,7 +26,8 @@ export class VariantAnalysisView extends AbstractWebview<ToVariantAnalysisMessag
|
||||
}
|
||||
|
||||
public async openView() {
|
||||
this.getPanel().reveal(undefined, true);
|
||||
const panel = await this.getPanel();
|
||||
panel.reveal(undefined, true);
|
||||
|
||||
await this.waitForPanelLoaded();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user