Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/workbench/api/common/extHostCodeInsets.ts
3296 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import { Emitter } from '../../../base/common/event.js';
7
import { DisposableStore } from '../../../base/common/lifecycle.js';
8
import { IExtensionDescription } from '../../../platform/extensions/common/extensions.js';
9
import { ExtHostTextEditor } from './extHostTextEditor.js';
10
import { ExtHostEditors } from './extHostTextEditors.js';
11
import { asWebviewUri, webviewGenericCspSource, WebviewRemoteInfo } from '../../contrib/webview/common/webview.js';
12
import type * as vscode from 'vscode';
13
import { ExtHostEditorInsetsShape, MainThreadEditorInsetsShape } from './extHost.protocol.js';
14
15
export class ExtHostEditorInsets implements ExtHostEditorInsetsShape {
16
17
private _handlePool = 0;
18
private readonly _disposables = new DisposableStore();
19
private _insets = new Map<number, { editor: vscode.TextEditor; inset: vscode.WebviewEditorInset; onDidReceiveMessage: Emitter<any> }>();
20
21
constructor(
22
private readonly _proxy: MainThreadEditorInsetsShape,
23
private readonly _editors: ExtHostEditors,
24
private readonly _remoteInfo: WebviewRemoteInfo
25
) {
26
27
// dispose editor inset whenever the hosting editor goes away
28
this._disposables.add(_editors.onDidChangeVisibleTextEditors(() => {
29
const visibleEditor = _editors.getVisibleTextEditors();
30
for (const value of this._insets.values()) {
31
if (visibleEditor.indexOf(value.editor) < 0) {
32
value.inset.dispose(); // will remove from `this._insets`
33
}
34
}
35
}));
36
}
37
38
dispose(): void {
39
this._insets.forEach(value => value.inset.dispose());
40
this._disposables.dispose();
41
}
42
43
createWebviewEditorInset(editor: vscode.TextEditor, line: number, height: number, options: vscode.WebviewOptions | undefined, extension: IExtensionDescription): vscode.WebviewEditorInset {
44
45
let apiEditor: ExtHostTextEditor | undefined;
46
for (const candidate of this._editors.getVisibleTextEditors(true)) {
47
if (candidate.value === editor) {
48
apiEditor = <ExtHostTextEditor>candidate;
49
break;
50
}
51
}
52
if (!apiEditor) {
53
throw new Error('not a visible editor');
54
}
55
56
const that = this;
57
const handle = this._handlePool++;
58
const onDidReceiveMessage = new Emitter<any>();
59
const onDidDispose = new Emitter<void>();
60
61
const webview = new class implements vscode.Webview {
62
63
private _html: string = '';
64
private _options: vscode.WebviewOptions = Object.create(null);
65
66
asWebviewUri(resource: vscode.Uri): vscode.Uri {
67
return asWebviewUri(resource, that._remoteInfo);
68
}
69
70
get cspSource(): string {
71
return webviewGenericCspSource;
72
}
73
74
set options(value: vscode.WebviewOptions) {
75
this._options = value;
76
that._proxy.$setOptions(handle, value);
77
}
78
79
get options(): vscode.WebviewOptions {
80
return this._options;
81
}
82
83
set html(value: string) {
84
this._html = value;
85
that._proxy.$setHtml(handle, value);
86
}
87
88
get html(): string {
89
return this._html;
90
}
91
92
get onDidReceiveMessage(): vscode.Event<any> {
93
return onDidReceiveMessage.event;
94
}
95
96
postMessage(message: any): Thenable<boolean> {
97
return that._proxy.$postMessage(handle, message);
98
}
99
};
100
101
const inset = new class implements vscode.WebviewEditorInset {
102
103
readonly editor: vscode.TextEditor = editor;
104
readonly line: number = line;
105
readonly height: number = height;
106
readonly webview: vscode.Webview = webview;
107
readonly onDidDispose: vscode.Event<void> = onDidDispose.event;
108
109
dispose(): void {
110
if (that._insets.has(handle)) {
111
that._insets.delete(handle);
112
that._proxy.$disposeEditorInset(handle);
113
onDidDispose.fire();
114
115
// final cleanup
116
onDidDispose.dispose();
117
onDidReceiveMessage.dispose();
118
}
119
}
120
};
121
122
this._proxy.$createEditorInset(handle, apiEditor.id, apiEditor.value.document.uri, line + 1, height, options || {}, extension.identifier, extension.extensionLocation);
123
this._insets.set(handle, { editor, inset, onDidReceiveMessage });
124
125
return inset;
126
}
127
128
$onDidDispose(handle: number): void {
129
const value = this._insets.get(handle);
130
if (value) {
131
value.inset.dispose();
132
}
133
}
134
135
$onDidReceiveMessage(handle: number, message: any): void {
136
const value = this._insets.get(handle);
137
value?.onDidReceiveMessage.fire(message);
138
}
139
}
140
141