diff --git a/extensions/ipynb/src/cellAttachmentRenderer.ts b/extensions/ipynb/src/cellAttachmentRenderer.ts index 69e294d57b9..4f3626d5a18 100644 --- a/extensions/ipynb/src/cellAttachmentRenderer.ts +++ b/extensions/ipynb/src/cellAttachmentRenderer.ts @@ -22,7 +22,7 @@ export async function activate(ctx: RendererContext) { md.renderer.rules.image = (tokens: MarkdownItToken[], idx: number, options, env, self) => { const token = tokens[idx]; const src = token.attrGet('src'); - const attachments: Record> = env.outputItem.metadata?.custom?.attachments; // this stores attachment entries for every image in the cell + const attachments: Record> = env.outputItem.metadata().custom?.attachments; if (attachments && src) { const imageAttachment = attachments[src.replace('attachment:', '')]; if (imageAttachment) { diff --git a/extensions/ipynb/src/common.ts b/extensions/ipynb/src/common.ts index de72fbbbfc3..047814ecfc1 100644 --- a/extensions/ipynb/src/common.ts +++ b/extensions/ipynb/src/common.ts @@ -44,7 +44,7 @@ export interface CellOutputMetadata { /** * Metadata we store in VS Code cells. - * This contains the original metadata from the Jupyuter cells. + * This contains the original metadata from the Jupyter cells. */ export interface CellMetadata { /** diff --git a/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts b/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts index eed6f5eb480..c3b91419cef 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts @@ -1025,31 +1025,33 @@ var requirejs = (function() { }); } - async showMarkupPreview(initialization: IMarkupCellInitialization) { + async showMarkupPreview(newContent: IMarkupCellInitialization) { if (this._disposed) { return; } - const entry = this.markupPreviewMapping.get(initialization.cellId); + const entry = this.markupPreviewMapping.get(newContent.cellId); if (!entry) { - return this.createMarkupPreview(initialization); + return this.createMarkupPreview(newContent); } - const sameContent = initialization.content === entry.content; - if (!sameContent || !entry.visible) { + const sameContent = newContent.content === entry.content; + const sameMetadata = newContent.metadata === entry.metadata; + if (!sameContent || !sameMetadata || !entry.visible) { this._sendMessageToWebview({ type: 'showMarkupCell', - id: initialization.cellId, - handle: initialization.cellHandle, + id: newContent.cellId, + handle: newContent.cellHandle, // If the content has not changed, we still want to make sure the // preview is visible but don't need to send anything over - content: sameContent ? undefined : initialization.content, - top: initialization.offset + content: sameContent ? undefined : newContent.content, + top: newContent.offset, + metadata: sameMetadata ? undefined : newContent.metadata }); } - - entry.content = initialization.content; - entry.offset = initialization.offset; + entry.metadata = newContent.metadata; + entry.content = newContent.content; + entry.offset = newContent.offset; entry.visible = true; } diff --git a/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewMessages.ts b/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewMessages.ts index 08b8489dcb3..f8cb6f80e31 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewMessages.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewMessages.ts @@ -316,6 +316,7 @@ export interface IShowMarkupCellMessage { readonly handle: number; readonly content: string | undefined; readonly top: number; + readonly metadata: NotebookCellMetadata | undefined; } export interface IUpdateSelectedMarkupCellsMessage { diff --git a/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts b/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts index dea460bd27d..3e86223876e 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts @@ -1035,7 +1035,7 @@ async function webviewPreloads(ctx: PreloadContext) { break; case 'showMarkupCell': - viewModel.showMarkupCell(event.data.id, event.data.top, event.data.content); + viewModel.showMarkupCell(event.data.id, event.data.top, event.data.content, event.data.metadata); break; case 'hideMarkupCells': @@ -1448,7 +1448,7 @@ async function webviewPreloads(ctx: PreloadContext) { let cell = this._markupCells.get(info.cellId); if (cell) { cell.element.style.visibility = info.visible ? 'visible' : 'hidden'; - await cell.updateContentAndRender(info.content); + await cell.updateContentAndRender(info.content, info.metadata); } else { cell = await this.createMarkupCell(info, info.offset, info.visible); } @@ -1462,14 +1462,14 @@ async function webviewPreloads(ctx: PreloadContext) { } } - public async updateMarkupContent(id: string, newContent: string): Promise { + public async updateMarkupContent(id: string, newContent: string, metadata: NotebookCellMetadata): Promise { const cell = this.getExpectedMarkupCell(id); - await cell?.updateContentAndRender(newContent); + await cell?.updateContentAndRender(newContent, metadata); } - public showMarkupCell(id: string, top: number, newContent: string | undefined): void { + public showMarkupCell(id: string, top: number, newContent: string | undefined, metadata: NotebookCellMetadata | undefined): void { const cell = this.getExpectedMarkupCell(id); - cell?.show(top, newContent); + cell?.show(top, newContent, metadata); } public hideMarkupCell(id: string): void { @@ -1633,11 +1633,11 @@ async function webviewPreloads(ctx: PreloadContext) { private readonly outputItem: rendererApi.OutputItem; /// Internal field that holds text content - private _content: { readonly value: string; readonly version: number }; + private _content: { readonly value: string; readonly version: number; readonly metadata: NotebookCellMetadata }; constructor(id: string, mime: string, content: string, top: number, metadata: NotebookCellMetadata) { this.id = id; - this._content = { value: content, version: 0 }; + this._content = { value: content, version: 0, metadata: metadata }; let resolveReady: () => void; this.ready = new Promise(r => resolveReady = r); @@ -1646,7 +1646,10 @@ async function webviewPreloads(ctx: PreloadContext) { this.outputItem = Object.freeze({ id, mime, - metadata, + + metadata: (): NotebookCellMetadata => { + return this._content.metadata; + }, text: (): string => { return this._content.value; @@ -1688,7 +1691,7 @@ async function webviewPreloads(ctx: PreloadContext) { this.addEventListeners(); - this.updateContentAndRender(this._content.value).then(() => { + this.updateContentAndRender(this._content.value, this._content.metadata).then(() => { resizeObserver.observe(this.element, this.id, false, this.id); resolveReady(); }); @@ -1738,8 +1741,8 @@ async function webviewPreloads(ctx: PreloadContext) { }); } - public async updateContentAndRender(newContent: string): Promise { - this._content = { value: newContent, version: this._content.version + 1 }; + public async updateContentAndRender(newContent: string, metadata: NotebookCellMetadata): Promise { + this._content = { value: newContent, version: this._content.version + 1, metadata }; await renderers.render(this.outputItem, this.element); @@ -1772,11 +1775,11 @@ async function webviewPreloads(ctx: PreloadContext) { }); } - public show(top: number, newContent: string | undefined): void { + public show(top: number, newContent: string | undefined, metadata: NotebookCellMetadata | undefined): void { this.element.style.visibility = 'visible'; this.element.style.top = `${top}px`; - if (typeof newContent === 'string') { - this.updateContentAndRender(newContent); + if (typeof newContent === 'string' || metadata) { + this.updateContentAndRender(newContent ?? this._content.value, metadata ?? this._content.metadata); } else { this.updateMarkupDimensions(); } @@ -1792,7 +1795,7 @@ async function webviewPreloads(ctx: PreloadContext) { } public rerender() { - this.updateContentAndRender(this._content.value); + this.updateContentAndRender(this._content.value, this._content.metadata); } public remove() { diff --git a/src/vs/workbench/contrib/notebook/browser/viewModel/markupCellViewModel.ts b/src/vs/workbench/contrib/notebook/browser/viewModel/markupCellViewModel.ts index b6adb4b5a59..d603fa80208 100644 --- a/src/vs/workbench/contrib/notebook/browser/viewModel/markupCellViewModel.ts +++ b/src/vs/workbench/contrib/notebook/browser/viewModel/markupCellViewModel.ts @@ -29,8 +29,10 @@ export class MarkupCellViewModel extends BaseCellViewModel implements ICellViewM public get renderedHtml(): string | undefined { return this._renderedHtml; } public set renderedHtml(value: string | undefined) { - this._renderedHtml = value; - this._onDidChangeState.fire({ contentChanged: true }); + if (this._renderedHtml !== value) { + this._renderedHtml = value; + this._onDidChangeState.fire({ contentChanged: true }); + } } get layoutInfo() {