Skip to content

Commit 6451298

Browse files
authored
Add static preloads notebook contribution (microsoft#163512)
For microsoft#163511
1 parent f55ddeb commit 6451298

File tree

12 files changed

+168
-41
lines changed

12 files changed

+168
-41
lines changed

src/vs/workbench/contrib/notebook/browser/diff/notebookTextDiffEditor.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -410,11 +410,11 @@ export class NotebookTextDiffEditor extends EditorPane implements INotebookTextD
410410
}
411411
}));
412412

413-
await this._createOriginalWebview(generateUuid(), this._model.original.resource);
413+
await this._createOriginalWebview(generateUuid(), this._model.original.viewType, this._model.original.resource);
414414
if (this._originalWebview) {
415415
this._modifiedResourceDisposableStore.add(this._originalWebview);
416416
}
417-
await this._createModifiedWebview(generateUuid(), this._model.modified.resource);
417+
await this._createModifiedWebview(generateUuid(), this._model.modified.viewType, this._model.modified.resource);
418418
if (this._modifiedWebview) {
419419
this._modifiedResourceDisposableStore.add(this._modifiedWebview);
420420
}
@@ -466,10 +466,10 @@ export class NotebookTextDiffEditor extends EditorPane implements INotebookTextD
466466
}));
467467
}
468468

469-
private async _createModifiedWebview(id: string, resource: URI): Promise<void> {
469+
private async _createModifiedWebview(id: string, viewType: string, resource: URI): Promise<void> {
470470
this._modifiedWebview?.dispose();
471471

472-
this._modifiedWebview = this.instantiationService.createInstance(BackLayerWebView, this, id, resource, {
472+
this._modifiedWebview = this.instantiationService.createInstance(BackLayerWebView, this, id, viewType, resource, {
473473
...this._notebookOptions.computeDiffWebviewOptions(),
474474
fontFamily: this._generateFontFamily()
475475
}, undefined) as BackLayerWebView<IDiffCellInfo>;
@@ -483,10 +483,10 @@ export class NotebookTextDiffEditor extends EditorPane implements INotebookTextD
483483
return this._fontInfo?.fontFamily ?? `"SF Mono", Monaco, Menlo, Consolas, "Ubuntu Mono", "Liberation Mono", "DejaVu Sans Mono", "Courier New", monospace`;
484484
}
485485

486-
private async _createOriginalWebview(id: string, resource: URI): Promise<void> {
486+
private async _createOriginalWebview(id: string, viewType: string, resource: URI): Promise<void> {
487487
this._originalWebview?.dispose();
488488

489-
this._originalWebview = this.instantiationService.createInstance(BackLayerWebView, this, id, resource, {
489+
this._originalWebview = this.instantiationService.createInstance(BackLayerWebView, this, id, viewType, resource, {
490490
...this._notebookOptions.computeDiffWebviewOptions(),
491491
fontFamily: this._generateFontFamily()
492492
}, undefined) as BackLayerWebView<IDiffCellInfo>;

src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1236,7 +1236,7 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditorD
12361236
}
12371237

12381238
if (!this._webview) {
1239-
this._createWebview(this.getId(), this.textModel.uri);
1239+
this._createWebview(this.getId(), this.textModel.viewType, this.textModel.uri);
12401240
}
12411241

12421242
this._webviewResolvePromise = (async () => {
@@ -1273,7 +1273,7 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditorD
12731273
return this._webviewResolvePromise;
12741274
}
12751275

1276-
private async _createWebview(id: string, resource: URI): Promise<void> {
1276+
private async _createWebview(id: string, viewType: string, resource: URI): Promise<void> {
12771277
const that = this;
12781278

12791279
this._webview = this.instantiationService.createInstance(BackLayerWebView, {
@@ -1294,7 +1294,7 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditorD
12941294
didDropMarkupCell: that._didDropMarkupCell.bind(that),
12951295
didEndDragMarkupCell: that._didEndDragMarkupCell.bind(that),
12961296
didResizeOutput: that._didResizeOutput.bind(that)
1297-
}, id, resource, {
1297+
}, id, viewType, resource, {
12981298
...this._notebookOptions.computeWebviewOptions(),
12991299
fontFamily: this._generateFontFamily()
13001300
}, this.notebookRendererMessaging.getScoped(this._uuid));
@@ -1306,7 +1306,7 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditorD
13061306
}
13071307

13081308
private async _attachModel(textModel: NotebookTextModel, viewState: INotebookEditorViewState | undefined, perf?: NotebookPerfMarks) {
1309-
await this._createWebview(this.getId(), textModel.uri);
1309+
await this._createWebview(this.getId(), textModel.viewType, textModel.uri);
13101310
this.viewModel = this.instantiationService.createInstance(NotebookViewModel, textModel.viewType, textModel, this._viewContext, this.getLayoutInfo(), { isReadOnly: this._readOnly });
13111311
this._viewContext.eventDispatcher.emit([new NotebookLayoutChangedEvent({ width: true, fontInfo: true }, this.getLayoutInfo())]);
13121312

src/vs/workbench/contrib/notebook/browser/notebookExtensionPoint.ts

Lines changed: 46 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,16 @@ export interface INotebookRendererContribution {
4242
readonly [NotebookRendererContribution.requiresMessaging]: RendererMessagingSpec;
4343
}
4444

45+
const NotebookPreloadContribution = Object.freeze({
46+
type: 'type',
47+
entrypoint: 'entrypoint',
48+
});
49+
50+
export interface INotebookPreloadContribution {
51+
readonly [NotebookPreloadContribution.type]: string;
52+
readonly [NotebookPreloadContribution.entrypoint]: string;
53+
}
54+
4555
const notebookProviderContribution: IJSONSchema = {
4656
description: nls.localize('contributes.notebook.provider', 'Contributes notebook document provider.'),
4757
type: 'array',
@@ -139,7 +149,6 @@ const notebookRendererContribution: IJSONSchema = {
139149
'optional',
140150
'never',
141151
],
142-
143152
enumDescriptions: [
144153
nls.localize('contributes.notebook.renderer.requiresMessaging.always', 'Messaging is required. The renderer will only be used when it\'s part of an extension that can be run in an extension host.'),
145154
nls.localize('contributes.notebook.renderer.requiresMessaging.optional', 'The renderer is better with messaging available, but it\'s not requried.'),
@@ -198,14 +207,40 @@ const notebookRendererContribution: IJSONSchema = {
198207
}
199208
};
200209

201-
export const notebooksExtensionPoint = ExtensionsRegistry.registerExtensionPoint<INotebookEditorContribution[]>(
202-
{
203-
extensionPoint: 'notebooks',
204-
jsonSchema: notebookProviderContribution
205-
});
210+
const notebookPreloadContribution: IJSONSchema = {
211+
description: nls.localize('contributes.preload.provider', 'Contributes notebook preloads.'),
212+
type: 'array',
213+
defaultSnippets: [{ body: [{ type: '', entrypoint: '' }] }],
214+
items: {
215+
type: 'object',
216+
required: [
217+
NotebookPreloadContribution.type,
218+
NotebookPreloadContribution.entrypoint
219+
],
220+
properties: {
221+
[NotebookPreloadContribution.type]: {
222+
type: 'string',
223+
description: nls.localize('contributes.preload.provider.viewType', 'Type of the notebook.'),
224+
},
225+
[NotebookPreloadContribution.entrypoint]: {
226+
type: 'string',
227+
description: nls.localize('contributes.preload.entrypoint', 'Path to file loaded in the webview.'),
228+
},
229+
}
230+
}
231+
};
232+
233+
export const notebooksExtensionPoint = ExtensionsRegistry.registerExtensionPoint<INotebookEditorContribution[]>({
234+
extensionPoint: 'notebooks',
235+
jsonSchema: notebookProviderContribution
236+
});
206237

207-
export const notebookRendererExtensionPoint = ExtensionsRegistry.registerExtensionPoint<INotebookRendererContribution[]>(
208-
{
209-
extensionPoint: 'notebookRenderer',
210-
jsonSchema: notebookRendererContribution
211-
});
238+
export const notebookRendererExtensionPoint = ExtensionsRegistry.registerExtensionPoint<INotebookRendererContribution[]>({
239+
extensionPoint: 'notebookRenderer',
240+
jsonSchema: notebookRendererContribution
241+
});
242+
243+
export const notebookPreloadExtensionPoint = ExtensionsRegistry.registerExtensionPoint<INotebookPreloadContribution[]>({
244+
extensionPoint: 'notebookPreload',
245+
jsonSchema: notebookPreloadContribution,
246+
});

src/vs/workbench/contrib/notebook/browser/services/notebookServiceImpl.ts

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,20 +23,20 @@ import { IFileService } from 'vs/platform/files/common/files';
2323
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
2424
import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage';
2525
import { Memento } from 'vs/workbench/common/memento';
26-
import { INotebookEditorContribution, notebookRendererExtensionPoint, notebooksExtensionPoint } from 'vs/workbench/contrib/notebook/browser/notebookExtensionPoint';
26+
import { INotebookEditorContribution, notebookPreloadExtensionPoint, notebookRendererExtensionPoint, notebooksExtensionPoint } from 'vs/workbench/contrib/notebook/browser/notebookExtensionPoint';
2727
import { INotebookEditorOptions } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
2828
import { NotebookDiffEditorInput } from 'vs/workbench/contrib/notebook/common/notebookDiffEditorInput';
2929
import { NotebookCellTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookCellTextModel';
3030
import { NotebookTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookTextModel';
31-
import { ACCESSIBLE_NOTEBOOK_DISPLAY_ORDER, CellUri, NotebookSetting, INotebookContributionData, INotebookExclusiveDocumentFilter, INotebookRendererInfo, INotebookTextModel, IOrderedMimeType, IOutputDto, MimeTypeDisplayOrder, NotebookData, NotebookEditorPriority, NotebookRendererMatch, NOTEBOOK_DISPLAY_ORDER, RENDERER_EQUIVALENT_EXTENSIONS, RENDERER_NOT_AVAILABLE, TransientOptions, NotebookExtensionDescription } from 'vs/workbench/contrib/notebook/common/notebookCommon';
31+
import { ACCESSIBLE_NOTEBOOK_DISPLAY_ORDER, CellUri, NotebookSetting, INotebookContributionData, INotebookExclusiveDocumentFilter, INotebookRendererInfo, INotebookTextModel, IOrderedMimeType, IOutputDto, MimeTypeDisplayOrder, NotebookData, NotebookEditorPriority, NotebookRendererMatch, NOTEBOOK_DISPLAY_ORDER, RENDERER_EQUIVALENT_EXTENSIONS, RENDERER_NOT_AVAILABLE, TransientOptions, NotebookExtensionDescription, INotebookStaticPreloadInfo } from 'vs/workbench/contrib/notebook/common/notebookCommon';
3232
import { NotebookEditorInput } from 'vs/workbench/contrib/notebook/common/notebookEditorInput';
3333
import { INotebookEditorModelResolverService } from 'vs/workbench/contrib/notebook/common/notebookEditorModelResolverService';
3434
import { updateEditorTopPadding } from 'vs/workbench/contrib/notebook/common/notebookOptions';
35-
import { NotebookOutputRendererInfo } from 'vs/workbench/contrib/notebook/common/notebookOutputRenderer';
35+
import { NotebookOutputRendererInfo, NotebookStaticPreloadInfo as NotebookStaticPreloadInfo } from 'vs/workbench/contrib/notebook/common/notebookOutputRenderer';
3636
import { NotebookEditorDescriptor, NotebookProviderInfo } from 'vs/workbench/contrib/notebook/common/notebookProvider';
3737
import { ComplexNotebookProviderInfo, INotebookContentProvider, INotebookSerializer, INotebookService, SimpleNotebookProviderInfo } from 'vs/workbench/contrib/notebook/common/notebookService';
3838
import { DiffEditorInputFactoryFunction, EditorInputFactoryFunction, EditorInputFactoryObject, IEditorResolverService, IEditorType, RegisteredEditorInfo, RegisteredEditorPriority, UntitledEditorInputFactoryFunction } from 'vs/workbench/services/editor/common/editorResolverService';
39-
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
39+
import { IExtensionService, isProposedApiEnabled } from 'vs/workbench/services/extensions/common/extensions';
4040
import { IExtensionPointUser } from 'vs/workbench/services/extensions/common/extensionsRegistry';
4141

4242
export class NotebookProviderInfoStore extends Disposable {
@@ -422,6 +422,9 @@ export class NotebookService extends Disposable implements INotebookService {
422422
private readonly _notebookRenderersInfoStore = this._instantiationService.createInstance(NotebookOutputRendererInfoStore);
423423
private readonly _onDidChangeOutputRenderers = this._register(new Emitter<void>());
424424
readonly onDidChangeOutputRenderers = this._onDidChangeOutputRenderers.event;
425+
426+
private readonly _notebookStaticPreloadInfoStore = new Set<NotebookStaticPreloadInfo>();
427+
425428
private readonly _models = new ResourceMap<ModelData>();
426429

427430
private readonly _onWillAddNotebookDocument = this._register(new Emitter<NotebookTextModel>());
@@ -490,6 +493,35 @@ export class NotebookService extends Disposable implements INotebookService {
490493
this._onDidChangeOutputRenderers.fire();
491494
});
492495

496+
notebookPreloadExtensionPoint.setHandler(extensions => {
497+
this._notebookStaticPreloadInfoStore.clear();
498+
499+
for (const extension of extensions) {
500+
if (!isProposedApiEnabled(extension.description, 'contribNotebookStaticPreloads')) {
501+
continue;
502+
}
503+
504+
for (const notebookContribution of extension.value) {
505+
if (!notebookContribution.entrypoint) { // avoid crashing
506+
extension.collector.error(`Notebook preload does not specify entry point`);
507+
continue;
508+
}
509+
510+
const type = notebookContribution.type;
511+
if (!type) {
512+
extension.collector.error(`Notebook preload does not specify type-property`);
513+
continue;
514+
}
515+
516+
this._notebookStaticPreloadInfoStore.add(new NotebookStaticPreloadInfo({
517+
type,
518+
extension: extension.description,
519+
entrypoint: notebookContribution.entrypoint,
520+
}));
521+
}
522+
}
523+
});
524+
493525
const updateOrder = () => {
494526
this._displayOrder = new MimeTypeDisplayOrder(
495527
this._configurationService.getValue<string[]>(NotebookSetting.displayOrder) || [],
@@ -671,6 +703,14 @@ export class NotebookService extends Disposable implements INotebookService {
671703
return this._notebookRenderersInfoStore.getAll();
672704
}
673705

706+
*getStaticPreloads(viewType: string): Iterable<INotebookStaticPreloadInfo> {
707+
for (const preload of this._notebookStaticPreloadInfoStore) {
708+
if (preload.type === viewType) {
709+
yield preload;
710+
}
711+
}
712+
}
713+
674714
// --- notebook documents: create, destory, retrieve, enumerate
675715

676716
createNotebookTextModel(viewType: string, uri: URI, data: NotebookData, transientOptions: TransientOptions): NotebookTextModel {

src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ import { IWebviewElement, IWebviewService, WebviewContentPurpose } from 'vs/work
4343
import { WebviewWindowDragMonitor } from 'vs/workbench/contrib/webview/browser/webviewWindowDragMonitor';
4444
import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
4545
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
46-
import { FromWebviewMessage, IAckOutputHeight, IClickedDataUrlMessage, ICodeBlockHighlightRequest, IContentWidgetTopRequest, IControllerPreload, ICreationContent, ICreationRequestMessage, IFindMatch, IMarkupCellInitialization, RendererMetadata, ToWebviewMessage } from './webviewMessages';
46+
import { FromWebviewMessage, IAckOutputHeight, IClickedDataUrlMessage, ICodeBlockHighlightRequest, IContentWidgetTopRequest, IControllerPreload, ICreationContent, ICreationRequestMessage, IFindMatch, IMarkupCellInitialization, RendererMetadata, StaticPreloadMetadata, ToWebviewMessage } from './webviewMessages';
4747
import { DeferredPromise } from 'vs/base/common/async';
4848

4949
export interface ICachedInset<K extends ICommonCellInfo> {
@@ -121,6 +121,7 @@ export class BackLayerWebView<T extends ICommonCellInfo> extends Disposable {
121121
constructor(
122122
public notebookEditor: INotebookDelegateForWebview,
123123
public readonly id: string,
124+
public readonly notebookViewType: string,
124125
public readonly documentUri: URI,
125126
private options: BacklayerWebviewOptions,
126127
private readonly rendererMessaging: IScopedRendererMessaging | undefined,
@@ -225,10 +226,12 @@ export class BackLayerWebView<T extends ICommonCellInfo> extends Disposable {
225226

226227
private generateContent(coreDependencies: string, baseUrl: string) {
227228
const renderersData = this.getRendererData();
229+
const preloadsData = this.getStaticPreloadsData();
228230
const preloadScript = preloadsScriptStr(
229231
this.options,
230232
{ dragAndDropEnabled: this.options.dragAndDropEnabled },
231233
renderersData,
234+
preloadsData,
232235
this.workspaceTrustManagementService.isWorkspaceTrusted(),
233236
this.configurationService.getValue<number>(NotebookSetting.textOutputLineLimit) ?? 30,
234237
this.nonce);
@@ -417,6 +420,12 @@ export class BackLayerWebView<T extends ICommonCellInfo> extends Disposable {
417420
});
418421
}
419422

423+
private getStaticPreloadsData(): StaticPreloadMetadata[] {
424+
return Array.from(this.notebookService.getStaticPreloads(this.notebookViewType), preload => {
425+
return { entrypoint: this.asWebviewUri(preload.entrypoint, preload.extensionLocation).toString().toString() };
426+
});
427+
}
428+
420429
private asWebviewUri(uri: URI, fromExtension: URI | undefined) {
421430
return asWebviewUri(uri, fromExtension?.scheme === Schemas.vscodeRemote ? { isRemote: true, authority: fromExtension.authority } : undefined);
422431
}
@@ -920,16 +929,17 @@ var requirejs = (function() {
920929
return webview;
921930
}
922931

923-
private _getResourceRootsCache() {
932+
private _getResourceRootsCache(): URI[] {
924933
const workspaceFolders = this.contextService.getWorkspace().folders.map(x => x.uri);
925934
const notebookDir = this.getNotebookBaseUri();
926935
return [
927-
...this.notebookService.getNotebookProviderResourceRoots(),
928-
...this.notebookService.getRenderers().map(x => dirname(x.entrypoint.path)),
929-
...workspaceFolders,
936+
this.notebookService.getNotebookProviderResourceRoots(),
937+
this.notebookService.getRenderers().map(x => dirname(x.entrypoint.path)),
938+
Array.from(this.notebookService.getStaticPreloads(this.notebookViewType), x => dirname(x.entrypoint)),
939+
workspaceFolders,
930940
notebookDir,
931-
...this.getBuiltinLocalResourceRoots()
932-
];
941+
this.getBuiltinLocalResourceRoots()
942+
].flat();
933943
}
934944

935945
private initializeWebViewState() {

src/vs/workbench/contrib/notebook/browser/view/renderers/webviewMessages.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,10 @@ export interface RendererMetadata {
281281
readonly isBuiltin: boolean;
282282
}
283283

284+
export interface StaticPreloadMetadata {
285+
readonly entrypoint: string;
286+
}
287+
284288
export interface IUpdateRenderersMessage {
285289
readonly type: 'updateRenderers';
286290
readonly rendererData: readonly RendererMetadata[];

0 commit comments

Comments
 (0)