From 7ab8a39a89775f3c09f5a2d6f0a4579c7d5c7fed Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Tue, 10 Jan 2023 10:16:59 -0800 Subject: [PATCH] Fix #132143. Softer image update on rerun. (#170917) * Fix #132143. Softer image update on rerun. * Output raw data update required. --- extensions/notebook-renderers/src/index.ts | 9 +++ .../model/notebookCellOutputTextModel.ts | 6 +- .../common/model/notebookCellTextModel.ts | 62 ++++++++++++++----- .../contrib/notebook/common/notebookCommon.ts | 2 +- 4 files changed, 60 insertions(+), 19 deletions(-) diff --git a/extensions/notebook-renderers/src/index.ts b/extensions/notebook-renderers/src/index.ts index f6c50998062..7d228911dbe 100644 --- a/extensions/notebook-renderers/src/index.ts +++ b/extensions/notebook-renderers/src/index.ts @@ -48,6 +48,14 @@ function renderImage(outputInfo: OutputItem, element: HTMLElement): IDisposable } }; + if (element.firstChild) { + const display = element.firstChild as HTMLElement; + if (display.firstChild && display.firstChild.nodeName === 'IMG' && display.firstChild instanceof HTMLImageElement) { + display.firstChild.src = src; + return disposable; + } + } + const image = document.createElement('img'); image.src = src; const display = document.createElement('div'); @@ -301,6 +309,7 @@ export const activate: ActivationFunction = (ctx) => { case 'image/jpeg': case 'image/git': { + disposables.get(outputInfo.id)?.dispose(); const disposable = renderImage(outputInfo, element); disposables.set(outputInfo.id, disposable); } diff --git a/src/vs/workbench/contrib/notebook/common/model/notebookCellOutputTextModel.ts b/src/vs/workbench/contrib/notebook/common/model/notebookCellOutputTextModel.ts index 64cf3c76b87..960896d7d1c 100644 --- a/src/vs/workbench/contrib/notebook/common/model/notebookCellOutputTextModel.ts +++ b/src/vs/workbench/contrib/notebook/common/model/notebookCellOutputTextModel.ts @@ -25,13 +25,13 @@ export class NotebookCellOutputTextModel extends Disposable implements ICellOutp } constructor( - readonly _rawOutput: IOutputDto + private _rawOutput: IOutputDto ) { super(); } - replaceData(items: IOutputItemDto[]) { - this._rawOutput.outputs = items; + replaceData(rawData: IOutputDto) { + this._rawOutput = rawData; this._onDidChangeData.fire(); } diff --git a/src/vs/workbench/contrib/notebook/common/model/notebookCellTextModel.ts b/src/vs/workbench/contrib/notebook/common/model/notebookCellTextModel.ts index 6534527216c..ceea9f5deb8 100644 --- a/src/vs/workbench/contrib/notebook/common/model/notebookCellTextModel.ts +++ b/src/vs/workbench/contrib/notebook/common/model/notebookCellTextModel.ts @@ -280,23 +280,25 @@ export class NotebookCellTextModel extends Disposable implements ICell { } spliceNotebookCellOutputs(splice: NotebookCellOutputsSplice): void { - this.outputs.splice(splice.start, splice.deleteCount, ...splice.newOutputs); - this._onDidChangeOutputs.fire(splice); + if (splice.deleteCount > 0 && splice.newOutputs.length > 0) { + const commonLen = Math.min(splice.deleteCount, splice.newOutputs.length); + // update + for (let i = 0; i < commonLen; i++) { + const currentOutput = this.outputs[splice.start + i]; + const newOutput = splice.newOutputs[i]; + + this.replaceOutput(currentOutput.outputId, newOutput); + } + + this.outputs.splice(splice.start + commonLen, splice.deleteCount - commonLen, ...splice.newOutputs.slice(commonLen)); + this._onDidChangeOutputs.fire({ start: splice.start + commonLen, deleteCount: splice.deleteCount - commonLen, newOutputs: splice.newOutputs.slice(commonLen) }); + } else { + this.outputs.splice(splice.start, splice.deleteCount, ...splice.newOutputs); + this._onDidChangeOutputs.fire(splice); + } } - changeOutputItems(outputId: string, append: boolean, items: IOutputItemDto[]): boolean { - const outputIndex = this.outputs.findIndex(output => output.outputId === outputId); - - if (outputIndex < 0) { - return false; - } - - const output = this.outputs[outputIndex]; - if (append) { - output.appendData(items); - } else { - output.replaceData(items); - } + private _optimizeOutputItems(output: ICellOutput) { if (output.outputs.length > 1 && output.outputs.every(item => isTextStreamMime(item.mime))) { // Look for the mimes in the items, and keep track of their order. // Merge the streams into one output item, per mime type. @@ -322,7 +324,37 @@ export class NotebookCellTextModel extends Disposable implements ICell { }); }); } + } + replaceOutput(outputId: string, newOutputItem: ICellOutput) { + const outputIndex = this.outputs.findIndex(output => output.outputId === outputId); + + if (outputIndex < 0) { + return false; + } + + const output = this.outputs[outputIndex]; + output.replaceData(newOutputItem); + this._optimizeOutputItems(output); + this._onDidChangeOutputItems.fire(); + return true; + } + + changeOutputItems(outputId: string, append: boolean, items: IOutputItemDto[]): boolean { + const outputIndex = this.outputs.findIndex(output => output.outputId === outputId); + + if (outputIndex < 0) { + return false; + } + + const output = this.outputs[outputIndex]; + if (append) { + output.appendData(items); + } else { + output.replaceData({ outputId: outputId, outputs: items, metadata: output.metadata }); + } + + this._optimizeOutputItems(output); this._onDidChangeOutputItems.fire(); return true; } diff --git a/src/vs/workbench/contrib/notebook/common/notebookCommon.ts b/src/vs/workbench/contrib/notebook/common/notebookCommon.ts index e365830fb25..575dbbbe4d5 100644 --- a/src/vs/workbench/contrib/notebook/common/notebookCommon.ts +++ b/src/vs/workbench/contrib/notebook/common/notebookCommon.ts @@ -205,7 +205,7 @@ export interface ICellOutput { metadata?: Record; outputId: string; onDidChangeData: Event; - replaceData(items: IOutputItemDto[]): void; + replaceData(items: IOutputDto): void; appendData(items: IOutputItemDto[]): void; }