Skip to content

Commit

Permalink
Add static preloads notebook contribution (#163512)
Browse files Browse the repository at this point in the history
  • Loading branch information
mjbvz authored Oct 14, 2022
1 parent f55ddeb commit 6451298
Show file tree
Hide file tree
Showing 12 changed files with 168 additions and 41 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down Expand Up @@ -466,10 +466,10 @@ export class NotebookTextDiffEditor extends EditorPane implements INotebookTextD
}));
}

private async _createModifiedWebview(id: string, resource: URI): Promise<void> {
private async _createModifiedWebview(id: string, viewType: string, resource: URI): Promise<void> {
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<IDiffCellInfo>;
Expand All @@ -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<void> {
private async _createOriginalWebview(id: string, viewType: string, resource: URI): Promise<void> {
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<IDiffCellInfo>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 () => {
Expand Down Expand Up @@ -1273,7 +1273,7 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditorD
return this._webviewResolvePromise;
}

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

this._webview = this.instantiationService.createInstance(BackLayerWebView, {
Expand All @@ -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));
Expand All @@ -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())]);

Expand Down
57 changes: 46 additions & 11 deletions src/vs/workbench/contrib/notebook/browser/notebookExtensionPoint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down Expand Up @@ -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.'),
Expand Down Expand Up @@ -198,14 +207,40 @@ const notebookRendererContribution: IJSONSchema = {
}
};

export const notebooksExtensionPoint = ExtensionsRegistry.registerExtensionPoint<INotebookEditorContribution[]>(
{
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<INotebookEditorContribution[]>({
extensionPoint: 'notebooks',
jsonSchema: notebookProviderContribution
});

export const notebookRendererExtensionPoint = ExtensionsRegistry.registerExtensionPoint<INotebookRendererContribution[]>(
{
extensionPoint: 'notebookRenderer',
jsonSchema: notebookRendererContribution
});
export const notebookRendererExtensionPoint = ExtensionsRegistry.registerExtensionPoint<INotebookRendererContribution[]>({
extensionPoint: 'notebookRenderer',
jsonSchema: notebookRendererContribution
});

export const notebookPreloadExtensionPoint = ExtensionsRegistry.registerExtensionPoint<INotebookPreloadContribution[]>({
extensionPoint: 'notebookPreload',
jsonSchema: notebookPreloadContribution,
});
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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<void>());
readonly onDidChangeOutputRenderers = this._onDidChangeOutputRenderers.event;

private readonly _notebookStaticPreloadInfoStore = new Set<NotebookStaticPreloadInfo>();

private readonly _models = new ResourceMap<ModelData>();

private readonly _onWillAddNotebookDocument = this._register(new Emitter<NotebookTextModel>());
Expand Down Expand Up @@ -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<string[]>(NotebookSetting.displayOrder) || [],
Expand Down Expand Up @@ -671,6 +703,14 @@ export class NotebookService extends Disposable implements INotebookService {
return this._notebookRenderersInfoStore.getAll();
}

*getStaticPreloads(viewType: string): Iterable<INotebookStaticPreloadInfo> {
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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<K extends ICommonCellInfo> {
Expand Down Expand Up @@ -121,6 +121,7 @@ export class BackLayerWebView<T extends ICommonCellInfo> 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,
Expand Down Expand Up @@ -225,10 +226,12 @@ export class BackLayerWebView<T extends ICommonCellInfo> 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<number>(NotebookSetting.textOutputLineLimit) ?? 30,
this.nonce);
Expand Down Expand Up @@ -417,6 +420,12 @@ export class BackLayerWebView<T extends ICommonCellInfo> 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);
}
Expand Down Expand Up @@ -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() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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[];
Expand Down
Loading

0 comments on commit 6451298

Please sign in to comment.