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

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

上级 df15db21
......@@ -27,12 +27,14 @@ namespace NotebookRendererContribution {
export const viewType = 'viewType';
export const displayName = 'displayName';
export const mimeTypes = 'mimeTypes';
export const entrypoint = 'entrypoint';
}
interface INotebookRendererContribution {
export interface INotebookRendererContribution {
readonly [NotebookRendererContribution.viewType]: string;
readonly [NotebookRendererContribution.displayName]: string;
readonly [NotebookRendererContribution.mimeTypes]?: readonly string[];
readonly [NotebookRendererContribution.entrypoint]?: string;
}
const notebookProviderContribution: IJSONSchema = {
......@@ -115,7 +117,11 @@ const notebookRendererContribution: IJSONSchema = {
items: {
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';
import { flatten } from 'vs/base/common/arrays';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
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 {
return resource.toString();
......@@ -287,8 +288,12 @@ export class NotebookService extends Disposable implements INotebookService, ICu
this.notebookRenderersInfoStore.add(new NotebookOutputRendererInfo({
id: notebookContribution.viewType,
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
let orderMimeTypes: IOrderedMimeType[] = [];
sorted.forEach(mimeType => {
let handlers = this.findBestMatchedRenderer(mimeType);
let handlers = this._findBestMatchedRenderer(mimeType);
if (handlers.length) {
const handler = handlers[0];
......@@ -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);
}
......
......@@ -261,6 +261,8 @@ function webviewPreloads() {
interface ICreateCellInfo {
outputId: string;
output?: unknown;
mimeType?: string;
element: HTMLElement;
}
......@@ -374,10 +376,21 @@ function webviewPreloads() {
outputNode.innerHTML = content;
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
domEval(outputNode);
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_notebook_message: true,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册