Merge pull request #2813 from github/koesie10/use-app-in-webview
Use `App` instead of `ExtensionContext` for webviews
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
import {
|
||||
WebviewPanel,
|
||||
ExtensionContext,
|
||||
window as Window,
|
||||
ViewColumn,
|
||||
Uri,
|
||||
@@ -9,6 +8,7 @@ import {
|
||||
} from "vscode";
|
||||
import { join } from "path";
|
||||
|
||||
import { App } from "../app";
|
||||
import { DisposableObject, DisposeHandler } from "../disposable-object";
|
||||
import { tmpDir } from "../../tmp-dir";
|
||||
import { getHtmlForWebview, WebviewMessage, WebviewKind } from "./webview-html";
|
||||
@@ -34,7 +34,7 @@ export abstract class AbstractWebview<
|
||||
|
||||
private panelResolves?: Array<(panel: WebviewPanel) => void>;
|
||||
|
||||
constructor(protected readonly ctx: ExtensionContext) {
|
||||
constructor(protected readonly app: App) {
|
||||
super();
|
||||
}
|
||||
|
||||
@@ -50,8 +50,6 @@ export abstract class AbstractWebview<
|
||||
|
||||
protected async getPanel(): Promise<WebviewPanel> {
|
||||
if (this.panel === undefined) {
|
||||
const { ctx } = this;
|
||||
|
||||
// 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.
|
||||
@@ -81,7 +79,7 @@ export abstract class AbstractWebview<
|
||||
localResourceRoots: [
|
||||
...(config.additionalOptions?.localResourceRoots ?? []),
|
||||
Uri.file(tmpDir.name),
|
||||
Uri.file(join(ctx.extensionPath, "out")),
|
||||
Uri.file(join(this.app.extensionPath, "out")),
|
||||
],
|
||||
},
|
||||
);
|
||||
@@ -99,19 +97,15 @@ export abstract class AbstractWebview<
|
||||
|
||||
protected setupPanel(panel: WebviewPanel, config: WebviewPanelConfig): void {
|
||||
this.push(
|
||||
panel.onDidDispose(
|
||||
() => {
|
||||
this.panel = undefined;
|
||||
this.panelLoaded = false;
|
||||
this.onPanelDispose();
|
||||
},
|
||||
null,
|
||||
this.ctx.subscriptions,
|
||||
),
|
||||
panel.onDidDispose(() => {
|
||||
this.panel = undefined;
|
||||
this.panelLoaded = false;
|
||||
this.onPanelDispose();
|
||||
}, null),
|
||||
);
|
||||
|
||||
panel.webview.html = getHtmlForWebview(
|
||||
this.ctx,
|
||||
this.app,
|
||||
panel.webview,
|
||||
config.view,
|
||||
{
|
||||
@@ -123,7 +117,6 @@ export abstract class AbstractWebview<
|
||||
panel.webview.onDidReceiveMessage(
|
||||
async (e) => this.onMessage(e),
|
||||
undefined,
|
||||
this.ctx.subscriptions,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { ExtensionContext, Uri, Webview } from "vscode";
|
||||
import { Uri, Webview } from "vscode";
|
||||
import { randomBytes } from "crypto";
|
||||
import { EOL } from "os";
|
||||
import { App } from "../app";
|
||||
|
||||
export type WebviewKind =
|
||||
| "results"
|
||||
@@ -19,7 +20,7 @@ export interface WebviewMessage {
|
||||
* Uses a content security policy that only loads the given script.
|
||||
*/
|
||||
export function getHtmlForWebview(
|
||||
ctx: ExtensionContext,
|
||||
app: App,
|
||||
webview: Webview,
|
||||
view: WebviewKind,
|
||||
{
|
||||
@@ -33,10 +34,13 @@ export function getHtmlForWebview(
|
||||
allowWasmEval: false,
|
||||
},
|
||||
): string {
|
||||
const scriptUriOnDisk = Uri.file(ctx.asAbsolutePath("out/webview.js"));
|
||||
const scriptUriOnDisk = Uri.joinPath(
|
||||
Uri.file(app.extensionPath),
|
||||
"out/webview.js",
|
||||
);
|
||||
|
||||
const stylesheetUrisOnDisk = [
|
||||
Uri.file(ctx.asAbsolutePath("out/webview.css")),
|
||||
Uri.joinPath(Uri.file(app.extensionPath), "out/webview.css"),
|
||||
];
|
||||
|
||||
// Convert the on-disk URIs into webview URIs.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ExtensionContext, ViewColumn } from "vscode";
|
||||
import { ViewColumn } from "vscode";
|
||||
|
||||
import {
|
||||
FromCompareViewMessage,
|
||||
@@ -25,6 +25,7 @@ import {
|
||||
} from "../common/vscode/abstract-webview";
|
||||
import { telemetryListener } from "../common/vscode/telemetry";
|
||||
import { redactableError } from "../common/errors";
|
||||
import { App } from "../common/app";
|
||||
|
||||
interface ComparePair {
|
||||
from: CompletedLocalQueryInfo;
|
||||
@@ -38,7 +39,7 @@ export class CompareView extends AbstractWebview<
|
||||
private comparePair: ComparePair | undefined;
|
||||
|
||||
constructor(
|
||||
ctx: ExtensionContext,
|
||||
app: App,
|
||||
private databaseManager: DatabaseManager,
|
||||
private cliServer: CodeQLCliServer,
|
||||
private logger: Logger,
|
||||
@@ -47,7 +48,7 @@ export class CompareView extends AbstractWebview<
|
||||
item: CompletedLocalQueryInfo,
|
||||
) => Promise<void>,
|
||||
) {
|
||||
super(ctx);
|
||||
super(app);
|
||||
}
|
||||
|
||||
async showResults(
|
||||
|
||||
@@ -396,10 +396,7 @@ export async function activate(
|
||||
),
|
||||
);
|
||||
|
||||
const variantAnalysisViewSerializer = new VariantAnalysisViewSerializer(
|
||||
ctx,
|
||||
app,
|
||||
);
|
||||
const variantAnalysisViewSerializer = new VariantAnalysisViewSerializer(app);
|
||||
Window.registerWebviewPanelSerializer(
|
||||
VariantAnalysisView.viewType,
|
||||
variantAnalysisViewSerializer,
|
||||
@@ -813,7 +810,7 @@ async function activateWithInstalledDistribution(
|
||||
|
||||
void extLogger.log("Initializing results panel interface.");
|
||||
const localQueryResultsView = new ResultsView(
|
||||
ctx,
|
||||
app,
|
||||
dbm,
|
||||
cliServer,
|
||||
queryServerLogger,
|
||||
@@ -836,7 +833,6 @@ async function activateWithInstalledDistribution(
|
||||
);
|
||||
|
||||
const variantAnalysisManager = new VariantAnalysisManager(
|
||||
ctx,
|
||||
app,
|
||||
cliServer,
|
||||
variantAnalysisStorageDir,
|
||||
@@ -888,7 +884,7 @@ async function activateWithInstalledDistribution(
|
||||
|
||||
void extLogger.log("Initializing compare view.");
|
||||
const compareView = new CompareView(
|
||||
ctx,
|
||||
app,
|
||||
dbm,
|
||||
cliServer,
|
||||
queryServerLogger,
|
||||
@@ -935,7 +931,6 @@ async function activateWithInstalledDistribution(
|
||||
ctx.subscriptions.push(debuggerUI);
|
||||
|
||||
const modelEditorModule = await ModelEditorModule.initialize(
|
||||
ctx,
|
||||
app,
|
||||
dbm,
|
||||
cliServer,
|
||||
|
||||
@@ -74,6 +74,7 @@ import { HistoryItemLabelProvider } from "../query-history/history-item-label-pr
|
||||
import { telemetryListener } from "../common/vscode/telemetry";
|
||||
import { redactableError } from "../common/errors";
|
||||
import { ResultsViewCommands } from "../common/commands";
|
||||
import { App } from "../common/app";
|
||||
|
||||
/**
|
||||
* results-view.ts
|
||||
@@ -168,13 +169,13 @@ export class ResultsView extends AbstractWebview<
|
||||
);
|
||||
|
||||
constructor(
|
||||
public ctx: vscode.ExtensionContext,
|
||||
app: App,
|
||||
private databaseManager: DatabaseManager,
|
||||
public cliServer: CodeQLCliServer,
|
||||
public logger: Logger,
|
||||
private labelProvider: HistoryItemLabelProvider,
|
||||
) {
|
||||
super(ctx);
|
||||
super(app);
|
||||
this.push(this._diagnosticCollection);
|
||||
this.push(
|
||||
vscode.window.onDidChangeTextEditorSelection(
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { ExtensionContext, window } from "vscode";
|
||||
import { window } from "vscode";
|
||||
import { App } from "../../common/app";
|
||||
import { DisposableObject } from "../../common/disposable-object";
|
||||
import { MethodModelingViewProvider } from "./method-modeling-view-provider";
|
||||
import { Method } from "../method";
|
||||
@@ -6,10 +7,10 @@ import { Method } from "../method";
|
||||
export class MethodModelingPanel extends DisposableObject {
|
||||
private readonly provider: MethodModelingViewProvider;
|
||||
|
||||
constructor(context: ExtensionContext) {
|
||||
constructor(app: App) {
|
||||
super();
|
||||
|
||||
this.provider = new MethodModelingViewProvider(context);
|
||||
this.provider = new MethodModelingViewProvider(app);
|
||||
this.push(
|
||||
window.registerWebviewViewProvider(
|
||||
MethodModelingViewProvider.viewType,
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import * as vscode from "vscode";
|
||||
import { WebviewViewProvider } from "vscode";
|
||||
import { Uri, WebviewViewProvider } from "vscode";
|
||||
import { getHtmlForWebview } from "../../common/vscode/webview-html";
|
||||
import { FromMethodModelingMessage } from "../../common/interface-types";
|
||||
import { telemetryListener } from "../../common/vscode/telemetry";
|
||||
import { showAndLogExceptionWithTelemetry } from "../../common/logging/notifications";
|
||||
import { extLogger } from "../../common/logging/vscode/loggers";
|
||||
import { App } from "../../common/app";
|
||||
import { redactableError } from "../../common/errors";
|
||||
import { Method } from "../method";
|
||||
|
||||
@@ -13,7 +14,7 @@ export class MethodModelingViewProvider implements WebviewViewProvider {
|
||||
|
||||
private webviewView: vscode.WebviewView | undefined = undefined;
|
||||
|
||||
constructor(private readonly context: vscode.ExtensionContext) {}
|
||||
constructor(private readonly app: App) {}
|
||||
|
||||
/**
|
||||
* This is called when a view first becomes visible. This may happen when the view is
|
||||
@@ -26,11 +27,11 @@ export class MethodModelingViewProvider implements WebviewViewProvider {
|
||||
) {
|
||||
webviewView.webview.options = {
|
||||
enableScripts: true,
|
||||
localResourceRoots: [this.context.extensionUri],
|
||||
localResourceRoots: [Uri.file(this.app.extensionPath)],
|
||||
};
|
||||
|
||||
const html = getHtmlForWebview(
|
||||
this.context,
|
||||
this.app,
|
||||
webviewView.webview,
|
||||
"method-modeling",
|
||||
{
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { ExtensionContext } from "vscode";
|
||||
import { ModelEditorView } from "./model-editor-view";
|
||||
import { ModelEditorCommands } from "../common/commands";
|
||||
import { CliVersionConstraint, CodeQLCliServer } from "../codeql-cli/cli";
|
||||
@@ -31,7 +30,6 @@ export class ModelEditorModule extends DisposableObject {
|
||||
private mostRecentlyActiveView: ModelEditorView | undefined = undefined;
|
||||
|
||||
private constructor(
|
||||
private readonly ctx: ExtensionContext,
|
||||
private readonly app: App,
|
||||
private readonly databaseManager: DatabaseManager,
|
||||
private readonly cliServer: CodeQLCliServer,
|
||||
@@ -41,7 +39,7 @@ export class ModelEditorModule extends DisposableObject {
|
||||
super();
|
||||
this.queryStorageDir = join(baseQueryStorageDir, "model-editor-results");
|
||||
this.methodsUsagePanel = this.push(new MethodsUsagePanel(cliServer));
|
||||
this.methodModelingPanel = this.push(new MethodModelingPanel(ctx));
|
||||
this.methodModelingPanel = this.push(new MethodModelingPanel(app));
|
||||
}
|
||||
|
||||
private handleViewBecameActive(view: ModelEditorView): void {
|
||||
@@ -59,7 +57,6 @@ export class ModelEditorModule extends DisposableObject {
|
||||
}
|
||||
|
||||
public static async initialize(
|
||||
ctx: ExtensionContext,
|
||||
app: App,
|
||||
databaseManager: DatabaseManager,
|
||||
cliServer: CodeQLCliServer,
|
||||
@@ -67,7 +64,6 @@ export class ModelEditorModule extends DisposableObject {
|
||||
queryStorageDir: string,
|
||||
): Promise<ModelEditorModule> {
|
||||
const modelEditorModule = new ModelEditorModule(
|
||||
ctx,
|
||||
app,
|
||||
databaseManager,
|
||||
cliServer,
|
||||
@@ -153,7 +149,6 @@ export class ModelEditorModule extends DisposableObject {
|
||||
});
|
||||
|
||||
const view = new ModelEditorView(
|
||||
this.ctx,
|
||||
this.app,
|
||||
this.databaseManager,
|
||||
this.cliServer,
|
||||
|
||||
@@ -1,10 +1,4 @@
|
||||
import {
|
||||
CancellationTokenSource,
|
||||
ExtensionContext,
|
||||
Uri,
|
||||
ViewColumn,
|
||||
window,
|
||||
} from "vscode";
|
||||
import { CancellationTokenSource, Uri, ViewColumn, window } from "vscode";
|
||||
import {
|
||||
AbstractWebview,
|
||||
WebviewPanelConfig,
|
||||
@@ -37,7 +31,6 @@ import { ExtensionPack } from "./shared/extension-pack";
|
||||
import { showFlowGeneration, showLlmGeneration } from "../config";
|
||||
import { Mode } from "./shared/mode";
|
||||
import { loadModeledMethods, saveModeledMethods } from "./modeled-method-fs";
|
||||
import { join } from "path";
|
||||
import { pickExtensionPack } from "./extension-pack-picker";
|
||||
import { getLanguageDisplayName } from "../common/query-language";
|
||||
import { AutoModeler } from "./auto-modeler";
|
||||
@@ -54,8 +47,7 @@ export class ModelEditorView extends AbstractWebview<
|
||||
private hideModeledMethods: boolean;
|
||||
|
||||
public constructor(
|
||||
ctx: ExtensionContext,
|
||||
private readonly app: App,
|
||||
protected readonly app: App,
|
||||
private readonly databaseManager: DatabaseManager,
|
||||
private readonly cliServer: CodeQLCliServer,
|
||||
private readonly queryRunner: QueryRunner,
|
||||
@@ -79,7 +71,7 @@ export class ModelEditorView extends AbstractWebview<
|
||||
view: ModelEditorView,
|
||||
) => boolean,
|
||||
) {
|
||||
super(ctx);
|
||||
super(app);
|
||||
|
||||
this.autoModeler = new AutoModeler(
|
||||
app,
|
||||
@@ -158,11 +150,13 @@ export class ModelEditorView extends AbstractWebview<
|
||||
preserveFocus: true,
|
||||
view: "model-editor",
|
||||
iconPath: {
|
||||
dark: Uri.file(
|
||||
join(this.ctx.extensionPath, "media/dark/symbol-misc.svg"),
|
||||
dark: Uri.joinPath(
|
||||
Uri.file(this.app.extensionPath),
|
||||
"media/dark/symbol-misc.svg",
|
||||
),
|
||||
light: Uri.file(
|
||||
join(this.ctx.extensionPath, "media/light/symbol-misc.svg"),
|
||||
light: Uri.joinPath(
|
||||
Uri.file(this.app.extensionPath),
|
||||
"media/light/symbol-misc.svg",
|
||||
),
|
||||
},
|
||||
};
|
||||
@@ -493,7 +487,6 @@ export class ModelEditorView extends AbstractWebview<
|
||||
}
|
||||
|
||||
const view = new ModelEditorView(
|
||||
this.ctx,
|
||||
this.app,
|
||||
this.databaseManager,
|
||||
this.cliServer,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ExtensionContext, ViewColumn } from "vscode";
|
||||
import { ViewColumn } from "vscode";
|
||||
import {
|
||||
AbstractWebview,
|
||||
WebviewPanelConfig,
|
||||
@@ -10,6 +10,7 @@ import {
|
||||
ToDataFlowPathsMessage,
|
||||
} from "../common/interface-types";
|
||||
import { DataFlowPaths } from "./shared/data-flow-paths";
|
||||
import { App } from "../common/app";
|
||||
import { redactableError } from "../common/errors";
|
||||
import { extLogger } from "../common/logging/vscode";
|
||||
import { showAndLogExceptionWithTelemetry } from "../common/logging";
|
||||
@@ -20,8 +21,8 @@ export class DataFlowPathsView extends AbstractWebview<
|
||||
> {
|
||||
public static readonly viewType = "codeQL.dataFlowPaths";
|
||||
|
||||
public constructor(ctx: ExtensionContext) {
|
||||
super(ctx);
|
||||
public constructor(app: App) {
|
||||
super(app);
|
||||
}
|
||||
|
||||
public async showDataFlows(dataFlowPaths: DataFlowPaths) {
|
||||
|
||||
@@ -10,7 +10,6 @@ import {
|
||||
CancellationToken,
|
||||
env,
|
||||
EventEmitter,
|
||||
ExtensionContext,
|
||||
Uri,
|
||||
ViewColumn,
|
||||
window as Window,
|
||||
@@ -116,7 +115,6 @@ export class VariantAnalysisManager
|
||||
>();
|
||||
|
||||
constructor(
|
||||
private readonly ctx: ExtensionContext,
|
||||
private readonly app: App,
|
||||
private readonly cliServer: CodeQLCliServer,
|
||||
private readonly storagePath: string,
|
||||
@@ -347,9 +345,7 @@ export class VariantAnalysisManager
|
||||
}
|
||||
if (!this.views.has(variantAnalysisId)) {
|
||||
// The view will register itself with the manager, so we don't need to do anything here.
|
||||
this.track(
|
||||
new VariantAnalysisView(this.ctx, this.app, variantAnalysisId, this),
|
||||
);
|
||||
this.track(new VariantAnalysisView(this.app, variantAnalysisId, this));
|
||||
}
|
||||
|
||||
const variantAnalysisView = this.views.get(variantAnalysisId)!;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ExtensionContext, WebviewPanel, WebviewPanelSerializer } from "vscode";
|
||||
import { WebviewPanel, WebviewPanelSerializer } from "vscode";
|
||||
import { VariantAnalysisView } from "./variant-analysis-view";
|
||||
import { VariantAnalysisState } from "../common/interface-types";
|
||||
import { VariantAnalysisViewManager } from "./variant-analysis-view-manager";
|
||||
@@ -11,10 +11,7 @@ export class VariantAnalysisViewSerializer implements WebviewPanelSerializer {
|
||||
|
||||
private manager?: VariantAnalysisViewManager<VariantAnalysisView>;
|
||||
|
||||
public constructor(
|
||||
private readonly ctx: ExtensionContext,
|
||||
private readonly app: App,
|
||||
) {}
|
||||
public constructor(private readonly app: App) {}
|
||||
|
||||
onExtensionLoaded(
|
||||
manager: VariantAnalysisViewManager<VariantAnalysisView>,
|
||||
@@ -65,7 +62,6 @@ export class VariantAnalysisViewSerializer implements WebviewPanelSerializer {
|
||||
}
|
||||
|
||||
const view = new VariantAnalysisView(
|
||||
this.ctx,
|
||||
this.app,
|
||||
variantAnalysisState.variantAnalysisId,
|
||||
manager,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ExtensionContext, ViewColumn } from "vscode";
|
||||
import { ViewColumn } from "vscode";
|
||||
import {
|
||||
AbstractWebview,
|
||||
WebviewPanelConfig,
|
||||
@@ -39,16 +39,15 @@ export class VariantAnalysisView
|
||||
private readonly dataFlowPathsView: DataFlowPathsView;
|
||||
|
||||
public constructor(
|
||||
ctx: ExtensionContext,
|
||||
private readonly app: App,
|
||||
protected readonly app: App,
|
||||
public readonly variantAnalysisId: number,
|
||||
private readonly manager: VariantAnalysisViewManager<VariantAnalysisView>,
|
||||
) {
|
||||
super(ctx);
|
||||
super(app);
|
||||
|
||||
manager.registerView(this);
|
||||
|
||||
this.dataFlowPathsView = new DataFlowPathsView(ctx);
|
||||
this.dataFlowPathsView = new DataFlowPathsView(app);
|
||||
}
|
||||
|
||||
public async openView() {
|
||||
|
||||
@@ -76,7 +76,6 @@ describe("Variant Analysis Manager", () => {
|
||||
extLogger,
|
||||
);
|
||||
variantAnalysisManager = new VariantAnalysisManager(
|
||||
extension.ctx,
|
||||
app,
|
||||
cli,
|
||||
storagePath,
|
||||
|
||||
@@ -51,7 +51,6 @@ describe("Variant Analysis Manager", () => {
|
||||
extLogger,
|
||||
);
|
||||
variantAnalysisManager = new VariantAnalysisManager(
|
||||
extension.ctx,
|
||||
app,
|
||||
cli,
|
||||
storagePath,
|
||||
|
||||
Reference in New Issue
Block a user