Fix selection of notebook renderers for outputs (#162068)

Fix selection of notebook renderers

This fixes selection of notebook renderers when multiple renderers exist for a given mime type
This commit is contained in:
Matt Bierner 2022-09-27 15:08:49 -07:00 committed by GitHub
parent 8f43917766
commit 0994daba5c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -1489,11 +1489,28 @@ async function webviewPreloads(ctx: PreloadContext) {
this._renderers.get(rendererId)?.disposeOutputItem(outputId);
}
public async render(info: rendererApi.OutputItem, element: HTMLElement, signal: AbortSignal): Promise<void> {
const renderers = Array.from(this._renderers.values())
.filter((renderer) => renderer.data.mimeTypes.includes(info.mime) && !renderer.data.extends);
public async render(info: rendererApi.OutputItem, preferredRendererId: string | undefined, element: HTMLElement, signal: AbortSignal): Promise<void> {
let renderer: Renderer | undefined;
if (!renderers.length) {
if (typeof preferredRendererId === 'string') {
renderer = Array.from(this._renderers.values())
.find((renderer) => renderer.data.id === preferredRendererId);
} else {
const renderers = Array.from(this._renderers.values())
.filter((renderer) => renderer.data.mimeTypes.includes(info.mime) && !renderer.data.extends);
if (renderers.length) {
// De-prioritize built-in renderers
renderers.sort((a, b) => +a.data.isBuiltin - +b.data.isBuiltin);
// Use first renderer we find in sorted list
renderer = renderers[0];
}
}
if (renderer) {
await renderer.renderOutputItem(info, element, signal);
} else {
const errorContainer = document.createElement('div');
const error = document.createElement('div');
@ -1509,15 +1526,7 @@ async function webviewPreloads(ctx: PreloadContext) {
element.innerText = '';
element.appendChild(errorContainer);
return;
}
// De-prioritize built-in renderers
renderers.sort((a, b) => +a.data.isBuiltin - +b.data.isBuiltin);
// Use first renderer we find in sorted list
await renderers[0].renderOutputItem(info, element, signal);
}
}();
@ -1874,7 +1883,7 @@ async function webviewPreloads(ctx: PreloadContext) {
const controller = new AbortController();
this.renderTaskAbort = controller;
try {
await renderers.render(this.outputItem, this.element, this.renderTaskAbort.signal);
await renderers.render(this.outputItem, undefined, this.element, this.renderTaskAbort.signal);
} finally {
if (this.renderTaskAbort === controller) {
this.renderTaskAbort = undefined;
@ -2001,7 +2010,7 @@ async function webviewPreloads(ctx: PreloadContext) {
public async renderOutputElement(data: webviewMessages.ICreationRequestMessage, preloadErrors: ReadonlyArray<Error | undefined>, signal: AbortSignal) {
const outputElement = this.createOutputElement(data);
await outputElement.render(data.content, preloadErrors, signal);
await outputElement.render(data.content, data.rendererId, preloadErrors, signal);
// don't hide until after this step so that the height is right
outputElement.element.style.visibility = data.initiallyHidden ? 'hidden' : '';
@ -2132,6 +2141,7 @@ async function webviewPreloads(ctx: PreloadContext) {
public readonly element: HTMLElement;
private _content?: {
readonly content: webviewMessages.ICreationContent;
readonly preferredRendererId: string | undefined;
readonly preloadErrors: ReadonlyArray<Error | undefined>;
};
private hasResizeObserver = false;
@ -2164,11 +2174,11 @@ async function webviewPreloads(ctx: PreloadContext) {
this.renderTaskAbort = undefined;
}
public async render(content: webviewMessages.ICreationContent, preloadErrors: ReadonlyArray<Error | undefined>, signal?: AbortSignal) {
public async render(content: webviewMessages.ICreationContent, preferredRendererId: string | undefined, preloadErrors: ReadonlyArray<Error | undefined>, signal?: AbortSignal) {
this.renderTaskAbort?.abort();
this.renderTaskAbort = undefined;
this._content = { content, preloadErrors };
this._content = { content, preferredRendererId, preloadErrors };
if (content.type === 0 /* RenderOutputType.Html */) {
const trustedHtml = ttPolicy?.createHTML(content.htmlContent) ?? content.htmlContent;
this.element.innerHTML = trustedHtml as string;
@ -2186,7 +2196,7 @@ async function webviewPreloads(ctx: PreloadContext) {
signal?.addEventListener('abort', () => controller.abort());
try {
await renderers.render(item, this.element, controller.signal);
await renderers.render(item, preferredRendererId, this.element, controller.signal);
} finally {
if (this.renderTaskAbort === controller) {
this.renderTaskAbort = undefined;
@ -2229,13 +2239,13 @@ async function webviewPreloads(ctx: PreloadContext) {
public rerender() {
if (this._content) {
this.render(this._content.content, this._content.preloadErrors);
this.render(this._content.content, this._content.preferredRendererId, this._content.preloadErrors);
}
}
public updateAndRerender(content: webviewMessages.ICreationContent) {
if (this._content) {
this._content = { content, preloadErrors: this._content.preloadErrors };
this._content = { content, preferredRendererId: this._content.preferredRendererId, preloadErrors: this._content.preloadErrors };
this.rerender();
}
}