From 0859bfe6e8045fa2afc16873162d538cd755280f Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Wed, 12 Oct 2022 20:15:53 -0700 Subject: [PATCH] Add static preloads notebook contribution For #163511 --- .../browser/diff/notebookTextDiffEditor.ts | 12 ++-- .../notebook/browser/notebookEditorWidget.ts | 8 +-- .../browser/notebookExtensionPoint.ts | 57 +++++++++++++++---- .../browser/services/notebookServiceImpl.ts | 48 ++++++++++++++-- .../view/renderers/backLayerWebView.ts | 24 +++++--- .../browser/view/renderers/webviewMessages.ts | 4 ++ .../browser/view/renderers/webviewPreloads.ts | 20 ++++--- .../contrib/notebook/common/notebookCommon.ts | 5 ++ .../notebook/common/notebookOutputRenderer.ts | 20 ++++++- .../notebook/common/notebookService.ts | 4 +- .../common/extensionsApiProposals.ts | 1 + ...roposed.contribNotebookStaticPreloads.d.ts | 6 ++ 12 files changed, 168 insertions(+), 41 deletions(-) create mode 100644 src/vscode-dts/vscode.proposed.contribNotebookStaticPreloads.d.ts diff --git a/src/vs/workbench/contrib/notebook/browser/diff/notebookTextDiffEditor.ts b/src/vs/workbench/contrib/notebook/browser/diff/notebookTextDiffEditor.ts index bcab942c8cc2f..751d6fb5d7ca9 100644 --- a/src/vs/workbench/contrib/notebook/browser/diff/notebookTextDiffEditor.ts +++ b/src/vs/workbench/contrib/notebook/browser/diff/notebookTextDiffEditor.ts @@ -410,11 +410,11 @@ export class NotebookTextDiffEditor extends EditorPane implements INotebookTextD } })); - await this._createOriginalWebview(generateUuid(), this._model.original.resource); + await this._createOriginalWebview(generateUuid(), this._model.original.viewType, this._model.original.resource); if (this._originalWebview) { this._modifiedResourceDisposableStore.add(this._originalWebview); } - await this._createModifiedWebview(generateUuid(), this._model.modified.resource); + await this._createModifiedWebview(generateUuid(), this._model.modified.viewType, this._model.modified.resource); if (this._modifiedWebview) { this._modifiedResourceDisposableStore.add(this._modifiedWebview); } @@ -466,10 +466,10 @@ export class NotebookTextDiffEditor extends EditorPane implements INotebookTextD })); } - private async _createModifiedWebview(id: string, resource: URI): Promise { + private async _createModifiedWebview(id: string, viewType: string, resource: URI): Promise { this._modifiedWebview?.dispose(); - this._modifiedWebview = this.instantiationService.createInstance(BackLayerWebView, this, id, resource, { + this._modifiedWebview = this.instantiationService.createInstance(BackLayerWebView, this, id, viewType, resource, { ...this._notebookOptions.computeDiffWebviewOptions(), fontFamily: this._generateFontFamily() }, undefined) as BackLayerWebView; @@ -483,10 +483,10 @@ export class NotebookTextDiffEditor extends EditorPane implements INotebookTextD return this._fontInfo?.fontFamily ?? `"SF Mono", Monaco, Menlo, Consolas, "Ubuntu Mono", "Liberation Mono", "DejaVu Sans Mono", "Courier New", monospace`; } - private async _createOriginalWebview(id: string, resource: URI): Promise { + private async _createOriginalWebview(id: string, viewType: string, resource: URI): Promise { this._originalWebview?.dispose(); - this._originalWebview = this.instantiationService.createInstance(BackLayerWebView, this, id, resource, { + this._originalWebview = this.instantiationService.createInstance(BackLayerWebView, this, id, viewType, resource, { ...this._notebookOptions.computeDiffWebviewOptions(), fontFamily: this._generateFontFamily() }, undefined) as BackLayerWebView; diff --git a/src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts b/src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts index 892021f85297a..e625d88cf97ad 100644 --- a/src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts +++ b/src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts @@ -1236,7 +1236,7 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditorD } if (!this._webview) { - this._createWebview(this.getId(), this.textModel.uri); + this._createWebview(this.getId(), this.textModel.viewType, this.textModel.uri); } this._webviewResolvePromise = (async () => { @@ -1273,7 +1273,7 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditorD return this._webviewResolvePromise; } - private async _createWebview(id: string, resource: URI): Promise { + private async _createWebview(id: string, viewType: string, resource: URI): Promise { const that = this; this._webview = this.instantiationService.createInstance(BackLayerWebView, { @@ -1294,7 +1294,7 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditorD didDropMarkupCell: that._didDropMarkupCell.bind(that), didEndDragMarkupCell: that._didEndDragMarkupCell.bind(that), didResizeOutput: that._didResizeOutput.bind(that) - }, id, resource, { + }, id, viewType, resource, { ...this._notebookOptions.computeWebviewOptions(), fontFamily: this._generateFontFamily() }, this.notebookRendererMessaging.getScoped(this._uuid)); @@ -1306,7 +1306,7 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditorD } private async _attachModel(textModel: NotebookTextModel, viewState: INotebookEditorViewState | undefined, perf?: NotebookPerfMarks) { - await this._createWebview(this.getId(), textModel.uri); + await this._createWebview(this.getId(), textModel.viewType, textModel.uri); this.viewModel = this.instantiationService.createInstance(NotebookViewModel, textModel.viewType, textModel, this._viewContext, this.getLayoutInfo(), { isReadOnly: this._readOnly }); this._viewContext.eventDispatcher.emit([new NotebookLayoutChangedEvent({ width: true, fontInfo: true }, this.getLayoutInfo())]); diff --git a/src/vs/workbench/contrib/notebook/browser/notebookExtensionPoint.ts b/src/vs/workbench/contrib/notebook/browser/notebookExtensionPoint.ts index f28fc03d29b8f..4b32dd1539e27 100644 --- a/src/vs/workbench/contrib/notebook/browser/notebookExtensionPoint.ts +++ b/src/vs/workbench/contrib/notebook/browser/notebookExtensionPoint.ts @@ -42,6 +42,16 @@ export interface INotebookRendererContribution { readonly [NotebookRendererContribution.requiresMessaging]: RendererMessagingSpec; } +const NotebookPreloadContribution = Object.freeze({ + type: 'type', + entrypoint: 'entrypoint', +}); + +export interface INotebookPreloadContribution { + readonly [NotebookPreloadContribution.type]: string; + readonly [NotebookPreloadContribution.entrypoint]: string; +} + const notebookProviderContribution: IJSONSchema = { description: nls.localize('contributes.notebook.provider', 'Contributes notebook document provider.'), type: 'array', @@ -139,7 +149,6 @@ const notebookRendererContribution: IJSONSchema = { 'optional', 'never', ], - enumDescriptions: [ 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.'), 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 = { } }; -export const notebooksExtensionPoint = ExtensionsRegistry.registerExtensionPoint( - { - extensionPoint: 'notebooks', - jsonSchema: notebookProviderContribution - }); +const notebookPreloadContribution: IJSONSchema = { + description: nls.localize('contributes.preload.provider', 'Contributes notebook preloads.'), + type: 'array', + defaultSnippets: [{ body: [{ type: '', entrypoint: '' }] }], + items: { + type: 'object', + required: [ + NotebookPreloadContribution.type, + NotebookPreloadContribution.entrypoint + ], + properties: { + [NotebookPreloadContribution.type]: { + type: 'string', + description: nls.localize('contributes.preload.provider.viewType', 'Type of the notebook.'), + }, + [NotebookPreloadContribution.entrypoint]: { + type: 'string', + description: nls.localize('contributes.preload.entrypoint', 'Path to file loaded in the webview.'), + }, + } + } +}; + +export const notebooksExtensionPoint = ExtensionsRegistry.registerExtensionPoint({ + extensionPoint: 'notebooks', + jsonSchema: notebookProviderContribution +}); -export const notebookRendererExtensionPoint = ExtensionsRegistry.registerExtensionPoint( - { - extensionPoint: 'notebookRenderer', - jsonSchema: notebookRendererContribution - }); +export const notebookRendererExtensionPoint = ExtensionsRegistry.registerExtensionPoint({ + extensionPoint: 'notebookRenderer', + jsonSchema: notebookRendererContribution +}); + +export const notebookPreloadExtensionPoint = ExtensionsRegistry.registerExtensionPoint({ + extensionPoint: 'notebookPreload', + jsonSchema: notebookPreloadContribution, +}); diff --git a/src/vs/workbench/contrib/notebook/browser/services/notebookServiceImpl.ts b/src/vs/workbench/contrib/notebook/browser/services/notebookServiceImpl.ts index 66d21da2abb0e..4242f32265191 100644 --- a/src/vs/workbench/contrib/notebook/browser/services/notebookServiceImpl.ts +++ b/src/vs/workbench/contrib/notebook/browser/services/notebookServiceImpl.ts @@ -23,20 +23,20 @@ import { IFileService } from 'vs/platform/files/common/files'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage'; import { Memento } from 'vs/workbench/common/memento'; -import { INotebookEditorContribution, notebookRendererExtensionPoint, notebooksExtensionPoint } from 'vs/workbench/contrib/notebook/browser/notebookExtensionPoint'; +import { INotebookEditorContribution, notebookPreloadExtensionPoint, notebookRendererExtensionPoint, notebooksExtensionPoint } from 'vs/workbench/contrib/notebook/browser/notebookExtensionPoint'; import { INotebookEditorOptions } from 'vs/workbench/contrib/notebook/browser/notebookBrowser'; import { NotebookDiffEditorInput } from 'vs/workbench/contrib/notebook/common/notebookDiffEditorInput'; import { NotebookCellTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookCellTextModel'; import { NotebookTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookTextModel'; -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'; +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'; import { NotebookEditorInput } from 'vs/workbench/contrib/notebook/common/notebookEditorInput'; import { INotebookEditorModelResolverService } from 'vs/workbench/contrib/notebook/common/notebookEditorModelResolverService'; import { updateEditorTopPadding } from 'vs/workbench/contrib/notebook/common/notebookOptions'; -import { NotebookOutputRendererInfo } from 'vs/workbench/contrib/notebook/common/notebookOutputRenderer'; +import { NotebookOutputRendererInfo, NotebookStaticPreloadInfo as NotebookStaticPreloadInfo } from 'vs/workbench/contrib/notebook/common/notebookOutputRenderer'; import { NotebookEditorDescriptor, NotebookProviderInfo } from 'vs/workbench/contrib/notebook/common/notebookProvider'; import { ComplexNotebookProviderInfo, INotebookContentProvider, INotebookSerializer, INotebookService, SimpleNotebookProviderInfo } from 'vs/workbench/contrib/notebook/common/notebookService'; import { DiffEditorInputFactoryFunction, EditorInputFactoryFunction, EditorInputFactoryObject, IEditorResolverService, IEditorType, RegisteredEditorInfo, RegisteredEditorPriority, UntitledEditorInputFactoryFunction } from 'vs/workbench/services/editor/common/editorResolverService'; -import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; +import { IExtensionService, isProposedApiEnabled } from 'vs/workbench/services/extensions/common/extensions'; import { IExtensionPointUser } from 'vs/workbench/services/extensions/common/extensionsRegistry'; export class NotebookProviderInfoStore extends Disposable { @@ -422,6 +422,9 @@ export class NotebookService extends Disposable implements INotebookService { private readonly _notebookRenderersInfoStore = this._instantiationService.createInstance(NotebookOutputRendererInfoStore); private readonly _onDidChangeOutputRenderers = this._register(new Emitter()); readonly onDidChangeOutputRenderers = this._onDidChangeOutputRenderers.event; + + private readonly _notebookStaticPreloadInfoStore = new Set(); + private readonly _models = new ResourceMap(); private readonly _onWillAddNotebookDocument = this._register(new Emitter()); @@ -490,6 +493,35 @@ export class NotebookService extends Disposable implements INotebookService { this._onDidChangeOutputRenderers.fire(); }); + notebookPreloadExtensionPoint.setHandler(extensions => { + this._notebookStaticPreloadInfoStore.clear(); + + for (const extension of extensions) { + if (!isProposedApiEnabled(extension.description, 'contribNotebookStaticPreloads')) { + continue; + } + + for (const notebookContribution of extension.value) { + if (!notebookContribution.entrypoint) { // avoid crashing + extension.collector.error(`Notebook preload does not specify entry point`); + continue; + } + + const type = notebookContribution.type; + if (!type) { + extension.collector.error(`Notebook preload does not specify type-property`); + continue; + } + + this._notebookStaticPreloadInfoStore.add(new NotebookStaticPreloadInfo({ + type, + extension: extension.description, + entrypoint: notebookContribution.entrypoint, + })); + } + } + }); + const updateOrder = () => { this._displayOrder = new MimeTypeDisplayOrder( this._configurationService.getValue(NotebookSetting.displayOrder) || [], @@ -671,6 +703,14 @@ export class NotebookService extends Disposable implements INotebookService { return this._notebookRenderersInfoStore.getAll(); } + *getStaticPreloads(viewType: string): Iterable { + for (const preload of this._notebookStaticPreloadInfoStore) { + if (preload.type === viewType) { + yield preload; + } + } + } + // --- notebook documents: create, destory, retrieve, enumerate createNotebookTextModel(viewType: string, uri: URI, data: NotebookData, transientOptions: TransientOptions): NotebookTextModel { diff --git a/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts b/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts index ba6810f0afbff..bbef3bc7abcc4 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts @@ -43,7 +43,7 @@ import { IWebviewElement, IWebviewService, WebviewContentPurpose } from 'vs/work import { WebviewWindowDragMonitor } from 'vs/workbench/contrib/webview/browser/webviewWindowDragMonitor'; import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; -import { FromWebviewMessage, IAckOutputHeight, IClickedDataUrlMessage, ICodeBlockHighlightRequest, IContentWidgetTopRequest, IControllerPreload, ICreationContent, ICreationRequestMessage, IFindMatch, IMarkupCellInitialization, RendererMetadata, ToWebviewMessage } from './webviewMessages'; +import { FromWebviewMessage, IAckOutputHeight, IClickedDataUrlMessage, ICodeBlockHighlightRequest, IContentWidgetTopRequest, IControllerPreload, ICreationContent, ICreationRequestMessage, IFindMatch, IMarkupCellInitialization, RendererMetadata, StaticPreloadMetadata, ToWebviewMessage } from './webviewMessages'; import { DeferredPromise } from 'vs/base/common/async'; export interface ICachedInset { @@ -121,6 +121,7 @@ export class BackLayerWebView extends Disposable { constructor( public notebookEditor: INotebookDelegateForWebview, public readonly id: string, + public readonly notebookViewType: string, public readonly documentUri: URI, private options: BacklayerWebviewOptions, private readonly rendererMessaging: IScopedRendererMessaging | undefined, @@ -225,10 +226,12 @@ export class BackLayerWebView extends Disposable { private generateContent(coreDependencies: string, baseUrl: string) { const renderersData = this.getRendererData(); + const preloadsData = this.getStaticPreloadsData(); const preloadScript = preloadsScriptStr( this.options, { dragAndDropEnabled: this.options.dragAndDropEnabled }, renderersData, + preloadsData, this.workspaceTrustManagementService.isWorkspaceTrusted(), this.configurationService.getValue(NotebookSetting.textOutputLineLimit) ?? 30, this.nonce); @@ -417,6 +420,12 @@ export class BackLayerWebView extends Disposable { }); } + private getStaticPreloadsData(): StaticPreloadMetadata[] { + return Array.from(this.notebookService.getStaticPreloads(this.notebookViewType), preload => { + return { entrypoint: this.asWebviewUri(preload.entrypoint, preload.extensionLocation).toString().toString() }; + }); + } + private asWebviewUri(uri: URI, fromExtension: URI | undefined) { return asWebviewUri(uri, fromExtension?.scheme === Schemas.vscodeRemote ? { isRemote: true, authority: fromExtension.authority } : undefined); } @@ -920,16 +929,17 @@ var requirejs = (function() { return webview; } - private _getResourceRootsCache() { + private _getResourceRootsCache(): URI[] { const workspaceFolders = this.contextService.getWorkspace().folders.map(x => x.uri); const notebookDir = this.getNotebookBaseUri(); return [ - ...this.notebookService.getNotebookProviderResourceRoots(), - ...this.notebookService.getRenderers().map(x => dirname(x.entrypoint.path)), - ...workspaceFolders, + this.notebookService.getNotebookProviderResourceRoots(), + this.notebookService.getRenderers().map(x => dirname(x.entrypoint.path)), + Array.from(this.notebookService.getStaticPreloads(this.notebookViewType), x => dirname(x.entrypoint)), + workspaceFolders, notebookDir, - ...this.getBuiltinLocalResourceRoots() - ]; + this.getBuiltinLocalResourceRoots() + ].flat(); } private initializeWebViewState() { diff --git a/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewMessages.ts b/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewMessages.ts index 8b0902ba129e8..5eea6e550cf24 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewMessages.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewMessages.ts @@ -281,6 +281,10 @@ export interface RendererMetadata { readonly isBuiltin: boolean; } +export interface StaticPreloadMetadata { + readonly entrypoint: string; +} + export interface IUpdateRenderersMessage { readonly type: 'updateRenderers'; readonly rendererData: readonly RendererMetadata[]; diff --git a/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts b/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts index 4907be7643d24..84c1985521362 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts @@ -69,6 +69,7 @@ interface PreloadContext { readonly style: PreloadStyles; readonly options: PreloadOptions; readonly rendererData: readonly webviewMessages.RendererMetadata[]; + readonly staticPreloadsData: readonly webviewMessages.StaticPreloadMetadata[]; readonly isWorkspaceTrusted: boolean; readonly lineLimit: number; } @@ -199,7 +200,7 @@ async function webviewPreloads(ctx: PreloadContext) { } }; - async function loadScriptSource(url: string, originalUri = url): Promise { + async function loadScriptSource(url: string, originalUri: string): Promise { const res = await fetch(url); const text = await res.text(); if (!res.ok) { @@ -246,11 +247,11 @@ async function webviewPreloads(ctx: PreloadContext) { return new Function(...args.map(([k]) => k), functionSrc)(...args.map(([, v]) => v)); }; - const runKernelPreload = async (url: string, originalUri: string): Promise => { + const runKernelPreload = async (url: string, originalUri: string, forceLoadAsModule: boolean): Promise => { const text = await loadScriptSource(url, originalUri); const isModule = /\bexport\b.*\bactivate\b/.test(text); try { - if (isModule) { + if (isModule || forceLoadAsModule) { const module: KernelPreloadModule = await __import(url); if (!module.activate) { console.error(`Notebook preload (${url}) looks like a module but does not export an activate function`); @@ -1140,7 +1141,7 @@ async function webviewPreloads(ctx: PreloadContext) { case 'preload': { const resources = event.data.resources; for (const { uri, originalUri } of resources) { - kernelPreloads.load(uri, originalUri); + kernelPreloads.load(uri, originalUri, false); } break; } @@ -1360,9 +1361,9 @@ async function webviewPreloads(ctx: PreloadContext) { * @param uri URI to load from * @param originalUri URI to show in an error message if the preload is invalid. */ - public load(uri: string, originalUri: string) { + public load(uri: string, originalUri: string, forceLoadAsModule: boolean) { const promise = Promise.all([ - runKernelPreload(uri, originalUri), + runKernelPreload(uri, originalUri, forceLoadAsModule), this.waitForAllCurrent(), ]); @@ -2126,6 +2127,10 @@ async function webviewPreloads(ctx: PreloadContext) { type: 'initialized' }); + for (const preload of ctx.staticPreloadsData) { + kernelPreloads.load(preload.entrypoint, preload.entrypoint, true); + } + function postNotebookMessage( type: T['type'], properties: Omit @@ -2355,11 +2360,12 @@ async function webviewPreloads(ctx: PreloadContext) { }(); } -export function preloadsScriptStr(styleValues: PreloadStyles, options: PreloadOptions, renderers: readonly webviewMessages.RendererMetadata[], isWorkspaceTrusted: boolean, lineLimit: number, nonce: string) { +export function preloadsScriptStr(styleValues: PreloadStyles, options: PreloadOptions, renderers: readonly webviewMessages.RendererMetadata[], preloads: readonly webviewMessages.StaticPreloadMetadata[], isWorkspaceTrusted: boolean, lineLimit: number, nonce: string) { const ctx: PreloadContext = { style: styleValues, options, rendererData: renderers, + staticPreloadsData: preloads, isWorkspaceTrusted, lineLimit, nonce, diff --git a/src/vs/workbench/contrib/notebook/common/notebookCommon.ts b/src/vs/workbench/contrib/notebook/common/notebookCommon.ts index 403a07a082fd1..13c5beb2320fe 100644 --- a/src/vs/workbench/contrib/notebook/common/notebookCommon.ts +++ b/src/vs/workbench/contrib/notebook/common/notebookCommon.ts @@ -176,6 +176,11 @@ export interface INotebookRendererInfo { matches(mimeType: string, kernelProvides: ReadonlyArray): NotebookRendererMatch; } +export interface INotebookStaticPreloadInfo { + readonly type: string; + readonly entrypoint: URI; + readonly extensionLocation: URI; +} export interface IOrderedMimeType { mimeType: string; diff --git a/src/vs/workbench/contrib/notebook/common/notebookOutputRenderer.ts b/src/vs/workbench/contrib/notebook/common/notebookOutputRenderer.ts index 72c2e6ebf3ea6..8400da97fa0c8 100644 --- a/src/vs/workbench/contrib/notebook/common/notebookOutputRenderer.ts +++ b/src/vs/workbench/contrib/notebook/common/notebookOutputRenderer.ts @@ -8,7 +8,7 @@ import { Iterable } from 'vs/base/common/iterator'; import { joinPath } from 'vs/base/common/resources'; import { URI } from 'vs/base/common/uri'; import { ExtensionIdentifier, IExtensionDescription } from 'vs/platform/extensions/common/extensions'; -import { INotebookRendererInfo, ContributedNotebookRendererEntrypoint, NotebookRendererMatch, RendererMessagingSpec, NotebookRendererEntrypoint } from 'vs/workbench/contrib/notebook/common/notebookCommon'; +import { INotebookRendererInfo, ContributedNotebookRendererEntrypoint, NotebookRendererMatch, RendererMessagingSpec, NotebookRendererEntrypoint, INotebookStaticPreloadInfo as INotebookStaticPreloadInfo } from 'vs/workbench/contrib/notebook/common/notebookCommon'; class DependencyList { private readonly value: ReadonlySet; @@ -118,3 +118,21 @@ export class NotebookOutputRendererInfo implements INotebookRendererInfo { return this.mimeTypeGlobs.some(pattern => pattern(mimeType)) || this.mimeTypes.some(pattern => pattern === mimeType); } } + +export class NotebookStaticPreloadInfo implements INotebookStaticPreloadInfo { + + readonly type: string; + readonly entrypoint: URI; + readonly extensionLocation: URI; + + constructor(descriptor: { + readonly type: string; + readonly entrypoint: string; + readonly extension: IExtensionDescription; + }) { + this.type = descriptor.type; + + this.entrypoint = joinPath(descriptor.extension.extensionLocation, descriptor.entrypoint); + this.extensionLocation = descriptor.extension.extensionLocation; + } +} diff --git a/src/vs/workbench/contrib/notebook/common/notebookService.ts b/src/vs/workbench/contrib/notebook/common/notebookService.ts index f67d9be987dd9..d599600383a1a 100644 --- a/src/vs/workbench/contrib/notebook/common/notebookService.ts +++ b/src/vs/workbench/contrib/notebook/common/notebookService.ts @@ -7,7 +7,7 @@ import { createDecorator } from 'vs/platform/instantiation/common/instantiation' import { URI } from 'vs/base/common/uri'; import { NotebookProviderInfo } from 'vs/workbench/contrib/notebook/common/notebookProvider'; import { Event } from 'vs/base/common/event'; -import { INotebookRendererInfo, NotebookData, TransientOptions, IOrderedMimeType, IOutputDto, INotebookContributionData, NotebookExtensionDescription } from 'vs/workbench/contrib/notebook/common/notebookCommon'; +import { INotebookRendererInfo, NotebookData, TransientOptions, IOrderedMimeType, IOutputDto, INotebookContributionData, NotebookExtensionDescription, INotebookStaticPreloadInfo } from 'vs/workbench/contrib/notebook/common/notebookCommon'; import { NotebookTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookTextModel'; import { CancellationToken } from 'vs/base/common/cancellation'; import { NotebookCellTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookCellTextModel'; @@ -73,6 +73,8 @@ export interface INotebookService { getRendererInfo(id: string): INotebookRendererInfo | undefined; getRenderers(): INotebookRendererInfo[]; + getStaticPreloads(viewType: string): Iterable; + /** Updates the preferred renderer for the given mimetype in the workspace. */ updateMimePreferredRenderer(viewType: string, mimeType: string, rendererId: string, otherMimetypes: readonly string[]): void; saveMimeDisplayOrder(target: ConfigurationTarget): void; diff --git a/src/vs/workbench/services/extensions/common/extensionsApiProposals.ts b/src/vs/workbench/services/extensions/common/extensionsApiProposals.ts index facd28600fb98..f461c58e37eee 100644 --- a/src/vs/workbench/services/extensions/common/extensionsApiProposals.ts +++ b/src/vs/workbench/services/extensions/common/extensionsApiProposals.ts @@ -14,6 +14,7 @@ export const allApiProposals = Object.freeze({ contribLabelFormatterWorkspaceTooltip: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.contribLabelFormatterWorkspaceTooltip.d.ts', contribMenuBarHome: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.contribMenuBarHome.d.ts', contribMergeEditorMenus: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.contribMergeEditorMenus.d.ts', + contribNotebookStaticPreloads: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.contribNotebookStaticPreloads.d.ts', contribRemoteHelp: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.contribRemoteHelp.d.ts', contribShareMenu: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.contribShareMenu.d.ts', contribViewsRemote: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.contribViewsRemote.d.ts', diff --git a/src/vscode-dts/vscode.proposed.contribNotebookStaticPreloads.d.ts b/src/vscode-dts/vscode.proposed.contribNotebookStaticPreloads.d.ts new file mode 100644 index 0000000000000..b01c68ebabbd4 --- /dev/null +++ b/src/vscode-dts/vscode.proposed.contribNotebookStaticPreloads.d.ts @@ -0,0 +1,6 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +// empty placeholder declaration for the `notebookPreload` contribution point