未验证 提交 0955c0e7 编写于 作者: C Connor Peet 提交者: GitHub

notebooks: initial implementation of 'pure' output renderers (#103125)

上级 df15db21
...@@ -27,12 +27,14 @@ namespace NotebookRendererContribution { ...@@ -27,12 +27,14 @@ namespace NotebookRendererContribution {
export const viewType = 'viewType'; export const viewType = 'viewType';
export const displayName = 'displayName'; export const displayName = 'displayName';
export const mimeTypes = 'mimeTypes'; export const mimeTypes = 'mimeTypes';
export const entrypoint = 'entrypoint';
} }
interface INotebookRendererContribution { export interface INotebookRendererContribution {
readonly [NotebookRendererContribution.viewType]: string; readonly [NotebookRendererContribution.viewType]: string;
readonly [NotebookRendererContribution.displayName]: string; readonly [NotebookRendererContribution.displayName]: string;
readonly [NotebookRendererContribution.mimeTypes]?: readonly string[]; readonly [NotebookRendererContribution.mimeTypes]?: readonly string[];
readonly [NotebookRendererContribution.entrypoint]?: string;
} }
const notebookProviderContribution: IJSONSchema = { const notebookProviderContribution: IJSONSchema = {
...@@ -115,7 +117,11 @@ const notebookRendererContribution: IJSONSchema = { ...@@ -115,7 +117,11 @@ const notebookRendererContribution: IJSONSchema = {
items: { items: {
type: 'string' type: 'string'
} }
} },
[NotebookRendererContribution.entrypoint]: {
type: 'string',
description: nls.localize('contributes.notebook.renderer.entrypoint', 'File to load in the webview to render the extension.'),
},
} }
} }
}; };
......
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { URI, UriComponents } from 'vs/base/common/uri';
import { INotebookRendererInfo, IOutputRenderResponse, IOutputRenderRequest } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { ExtensionIdentifier, IExtensionDescription } from 'vs/platform/extensions/common/extensions';
import { joinPath } from 'vs/base/common/resources';
/**
* A 'stub' output renderer used when the contribution has an `entrypoint`
* property. Include the entrypoint as its reload and renders an empty string.
*/
export class PureNotebookOutputRenderer implements INotebookRendererInfo {
public readonly extensionId: ExtensionIdentifier;
public readonly extensionLocation: URI;
public readonly preloads: URI[];
constructor(public readonly id: string, extension: IExtensionDescription, entrypoint: string) {
this.extensionId = extension.identifier;
this.extensionLocation = extension.extensionLocation;
this.preloads = [joinPath(extension.extensionLocation, entrypoint)];
}
public render(uri: URI, request: IOutputRenderRequest<UriComponents>): Promise<IOutputRenderResponse<UriComponents> | undefined> {
return this.render2(uri, request);
}
public render2<T>(_uri: URI, request: IOutputRenderRequest<T>): Promise<IOutputRenderResponse<T> | undefined> {
return Promise.resolve({
items: request.items.map(cellInfo => ({
key: cellInfo.key,
outputs: cellInfo.outputs.map(output => ({
index: output.index,
outputId: output.outputId,
mimeType: output.mimeType,
handlerId: this.id,
// todo@connor4312: temp approach exploring this API:
transformedOutput: `<script class="vscode-pure-data" type="application/json">
${JSON.stringify({ mimeType: output.mimeType, output: output.output })}
</script>`
}))
}))
});
}
}
...@@ -31,6 +31,7 @@ import { generateUuid } from 'vs/base/common/uuid'; ...@@ -31,6 +31,7 @@ import { generateUuid } from 'vs/base/common/uuid';
import { flatten } from 'vs/base/common/arrays'; import { flatten } from 'vs/base/common/arrays';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { NotebookKernelProviderAssociationRegistry, updateNotebookKernelProvideAssociationSchema, NotebookViewTypesExtensionRegistry } from 'vs/workbench/contrib/notebook/browser/notebookKernelAssociation'; import { NotebookKernelProviderAssociationRegistry, updateNotebookKernelProvideAssociationSchema, NotebookViewTypesExtensionRegistry } from 'vs/workbench/contrib/notebook/browser/notebookKernelAssociation';
import { PureNotebookOutputRenderer } from 'vs/workbench/contrib/notebook/browser/notebookPureOutputRenderer';
function MODEL_ID(resource: URI): string { function MODEL_ID(resource: URI): string {
return resource.toString(); return resource.toString();
...@@ -287,8 +288,12 @@ export class NotebookService extends Disposable implements INotebookService, ICu ...@@ -287,8 +288,12 @@ export class NotebookService extends Disposable implements INotebookService, ICu
this.notebookRenderersInfoStore.add(new NotebookOutputRendererInfo({ this.notebookRenderersInfoStore.add(new NotebookOutputRendererInfo({
id: notebookContribution.viewType, id: notebookContribution.viewType,
displayName: notebookContribution.displayName, displayName: notebookContribution.displayName,
mimeTypes: notebookContribution.mimeTypes || [] mimeTypes: notebookContribution.mimeTypes || [],
})); }));
if (notebookContribution.entrypoint) {
this._notebookRenderers.set(notebookContribution.viewType, new PureNotebookOutputRenderer(notebookContribution.viewType, extension.description, notebookContribution.entrypoint));
}
} }
} }
...@@ -690,7 +695,7 @@ export class NotebookService extends Disposable implements INotebookService, ICu ...@@ -690,7 +695,7 @@ export class NotebookService extends Disposable implements INotebookService, ICu
let orderMimeTypes: IOrderedMimeType[] = []; let orderMimeTypes: IOrderedMimeType[] = [];
sorted.forEach(mimeType => { sorted.forEach(mimeType => {
let handlers = this.findBestMatchedRenderer(mimeType); let handlers = this._findBestMatchedRenderer(mimeType);
if (handlers.length) { if (handlers.length) {
const handler = handlers[0]; const handler = handlers[0];
...@@ -734,7 +739,7 @@ export class NotebookService extends Disposable implements INotebookService, ICu ...@@ -734,7 +739,7 @@ export class NotebookService extends Disposable implements INotebookService, ICu
}; };
} }
findBestMatchedRenderer(mimeType: string): readonly NotebookOutputRendererInfo[] { private _findBestMatchedRenderer(mimeType: string): readonly NotebookOutputRendererInfo[] {
return this.notebookRenderersInfoStore.getContributedRenderer(mimeType); return this.notebookRenderersInfoStore.getContributedRenderer(mimeType);
} }
......
...@@ -261,6 +261,8 @@ function webviewPreloads() { ...@@ -261,6 +261,8 @@ function webviewPreloads() {
interface ICreateCellInfo { interface ICreateCellInfo {
outputId: string; outputId: string;
output?: unknown;
mimeType?: string;
element: HTMLElement; element: HTMLElement;
} }
...@@ -374,10 +376,21 @@ function webviewPreloads() { ...@@ -374,10 +376,21 @@ function webviewPreloads() {
outputNode.innerHTML = content; outputNode.innerHTML = content;
cellOutputContainer.appendChild(outputNode); cellOutputContainer.appendChild(outputNode);
let pureData: { mimeType: string, output: unknown } | undefined;
const outputScript = cellOutputContainer.querySelector('script.vscode-pure-data');
if (outputScript) {
try { pureData = JSON.parse(outputScript.innerHTML); } catch { }
}
// eval // eval
domEval(outputNode); domEval(outputNode);
resizeObserve(outputNode, outputId); resizeObserve(outputNode, outputId);
onDidCreateOutput.fire([data.apiNamespace, { element: outputNode, outputId }]); onDidCreateOutput.fire([data.apiNamespace, {
element: outputNode,
output: pureData?.output,
mimeType: pureData?.mimeType,
outputId
}]);
vscode.postMessage({ vscode.postMessage({
__vscode_notebook_message: true, __vscode_notebook_message: true,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册