mirror of
https://github.com/Microsoft/vscode
synced 2024-08-28 05:19:39 +00:00
notebooks: initial implementation of 'pure' output renderers (#103125)
This commit is contained in:
parent
df15db2123
commit
0955c0e78f
|
@ -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.'),
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* 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,
|
||||
|
|
Loading…
Reference in a new issue