From 4bced156d16df6d5a6443e26e70f27bde3bef60c Mon Sep 17 00:00:00 2001 From: rebornix Date: Tue, 18 Feb 2020 17:32:25 -0800 Subject: [PATCH] notebook cell update with renderer updates. --- .../api/browser/mainThreadNotebook.ts | 14 +-- .../workbench/api/common/extHost.protocol.ts | 4 +- .../workbench/api/common/extHostNotebook.ts | 99 ++++++++++++++++--- 3 files changed, 96 insertions(+), 21 deletions(-) diff --git a/src/vs/workbench/api/browser/mainThreadNotebook.ts b/src/vs/workbench/api/browser/mainThreadNotebook.ts index 2f4c1e36852..12242914859 100644 --- a/src/vs/workbench/api/browser/mainThreadNotebook.ts +++ b/src/vs/workbench/api/browser/mainThreadNotebook.ts @@ -278,14 +278,14 @@ export class MainThreadNotebooks extends Disposable implements MainThreadNoteboo return handle; } - async $spliceNotebookCells(viewType: string, resource: UriComponents, splices: NotebookCellsSplice[]): Promise { + async $spliceNotebookCells(viewType: string, resource: UriComponents, splices: NotebookCellsSplice[], renderers: number[]): Promise { let controller = this._notebookProviders.get(viewType); - controller?.spliceNotebookCells(resource, splices); + controller?.spliceNotebookCells(resource, splices, renderers); } - async $spliceNotebookCellOutputs(viewType: string, resource: UriComponents, cellHandle: number, splices: NotebookCellOutputsSplice[]): Promise { + async $spliceNotebookCellOutputs(viewType: string, resource: UriComponents, cellHandle: number, splices: NotebookCellOutputsSplice[], renderers: number[]): Promise { let controller = this._notebookProviders.get(viewType); - controller?.spliceNotebookCellOutputs(resource, cellHandle, splices); + controller?.spliceNotebookCellOutputs(resource, cellHandle, splices, renderers); } async executeNotebook(viewType: string, uri: URI): Promise { @@ -320,13 +320,15 @@ export class MainThreadNotebookController implements IMainNotebookController { return undefined; } - spliceNotebookCells(resource: UriComponents, splices: NotebookCellsSplice[]): void { + spliceNotebookCells(resource: UriComponents, splices: NotebookCellsSplice[], renderers: number[]): void { let mainthreadNotebook = this._mapping.get(URI.from(resource).toString()); + mainthreadNotebook?.updateRenderers(renderers); mainthreadNotebook?.spliceNotebookCells(splices); } - spliceNotebookCellOutputs(resource: UriComponents, cellHandle: number, splices: NotebookCellOutputsSplice[]): void { + spliceNotebookCellOutputs(resource: UriComponents, cellHandle: number, splices: NotebookCellOutputsSplice[], renderers: number[]): void { let mainthreadNotebook = this._mapping.get(URI.from(resource).toString()); + mainthreadNotebook?.updateRenderers(renderers); mainthreadNotebook?.spliceNotebookCellOutputs(cellHandle, splices); } diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index dd108fa6906..d599c270bc7 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -661,8 +661,8 @@ export interface MainThreadNotebookShape extends IDisposable { $unregisterNotebookRenderer(handle: number): Promise; $createNotebookDocument(handle: number, viewType: string, resource: UriComponents): Promise; $updateNotebookLanguages(viewType: string, resource: UriComponents, languages: string[]): Promise; - $spliceNotebookCells(viewType: string, resource: UriComponents, splices: NotebookCellsSplice[]): Promise; - $spliceNotebookCellOutputs(viewType: string, resource: UriComponents, cellHandle: number, splices: NotebookCellOutputsSplice[]): Promise; + $spliceNotebookCells(viewType: string, resource: UriComponents, splices: NotebookCellsSplice[], renderers: number[]): Promise; + $spliceNotebookCellOutputs(viewType: string, resource: UriComponents, cellHandle: number, splices: NotebookCellOutputsSplice[], renderers: number[]): Promise; } export interface MainThreadUrlsShape extends IDisposable { diff --git a/src/vs/workbench/api/common/extHostNotebook.ts b/src/vs/workbench/api/common/extHostNotebook.ts index 08a08419887..2379c1c4eb6 100644 --- a/src/vs/workbench/api/common/extHostNotebook.ts +++ b/src/vs/workbench/api/common/extHostNotebook.ts @@ -5,7 +5,7 @@ import * as vscode from 'vscode'; import * as glob from 'vs/base/common/glob'; -import { ExtHostNotebookShape, IMainContext, MainThreadNotebookShape, MainContext, ICellDto } from 'vs/workbench/api/common/extHost.protocol'; +import { ExtHostNotebookShape, IMainContext, MainThreadNotebookShape, MainContext, ICellDto, NotebookCellsSplice, NotebookCellOutputsSplice } from 'vs/workbench/api/common/extHost.protocol'; import { IExtensionDescription } from 'vs/platform/extensions/common/extensions'; import { Disposable as VSCodeDisposable } from './extHostTypes'; import { URI, UriComponents } from 'vs/base/common/uri'; @@ -13,7 +13,7 @@ import { DisposableStore } from 'vs/base/common/lifecycle'; import { readonly } from 'vs/base/common/errors'; import { Emitter, Event } from 'vs/base/common/event'; import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors'; -import { INotebookDisplayOrder } from 'vs/workbench/contrib/notebook/common/notebookCommon'; +import { INotebookDisplayOrder, IGenericOutput } from 'vs/workbench/contrib/notebook/common/notebookCommon'; import { ISplice } from 'vs/base/common/sequence'; interface ExtHostOutputDisplayOrder { @@ -109,7 +109,7 @@ export class ExtHostCell implements vscode.NotebookCell { } set outputs(newOutputs: any[]) { - let diffs = diff(this._outputs, newOutputs, (a) => { + let diffs = diff(this._outputs || [], newOutputs || [], (a) => { return this._outputMapping.has(a); }); @@ -177,7 +177,7 @@ export class ExtHostNotebookDocument implements vscode.NotebookDocument { diff.toInsert.forEach(cell => { this._cellDisposableMapping.set(cell.handle, new DisposableStore()); this._cellDisposableMapping.get(cell.handle)?.add(cell.onDidChangeOutputs((outputDiffs) => { - this._proxy.$spliceNotebookCellOutputs(this.viewType, this.uri, cell.handle, outputDiffs.map(diff => [diff.start, diff.deleteCount, diff.toInsert])); + this.eventuallyUpdateCellOutputs(cell, outputDiffs); })); }); }); @@ -227,21 +227,94 @@ export class ExtHostNotebookDocument implements vscode.NotebookDocument { get isDirty() { return false; } eventuallyUpdateCells(diffs: ISplice[]) { - this._proxy.$spliceNotebookCells( - this.viewType, - this.uri, - diffs.map(diff => - [diff.start, diff.deleteCount, diff.toInsert.map(cell => ({ + let renderers = new Set(); + let diffDtos: NotebookCellsSplice[] = []; + + diffDtos = diffs.map(diff => { + let inserts = diff.toInsert; + + let cellDtos = inserts.map(cell => { + let outputs = cell.outputs; + if (outputs && outputs.length) { + outputs = outputs.map(output => { + let richestMimeType: string | undefined = undefined; + + if (this.renderingHandler.outputDisplayOrder?.userOrder || this._parsedDisplayOrder.length > 0) { + richestMimeType = this.findRichestMimeType(output); + } + + let transformedOutput: vscode.CellOutput | undefined = undefined; + + if (richestMimeType) { + let handler = this.renderingHandler.findBestMatchedRenderer(richestMimeType); + if (handler) { + renderers.add(handler.handle); + transformedOutput = handler?.render(this, cell, output); + + output = transformedOutput; + output.pickedMimeType = richestMimeType; + } + } + + return output; + }); + } + + return { handle: cell.handle, source: cell.source, language: cell.language, cell_type: cell.cell_type, - outputs: cell.outputs - }))] - ) + outputs: outputs, + isDirty: false + }; + }); + + return [diff.start, diff.deleteCount, cellDtos]; + }); + + this._proxy.$spliceNotebookCells( + this.viewType, + this.uri, + diffDtos, + Array.from(renderers) ); } + eventuallyUpdateCellOutputs(cell: ExtHostCell, diffs: ISplice[]) { + let renderers = new Set(); + let outputDtos: NotebookCellOutputsSplice[] = diffs.map(diff => { + let outputs = diff.toInsert; + + outputs = outputs.map(output => { + let richestMimeType: string | undefined = undefined; + + if (this.renderingHandler.outputDisplayOrder?.userOrder || this._parsedDisplayOrder.length > 0) { + richestMimeType = this.findRichestMimeType(output); + } + + let transformedOutput: vscode.CellOutput | undefined = undefined; + + if (richestMimeType) { + let handler = this.renderingHandler.findBestMatchedRenderer(richestMimeType); + if (handler) { + renderers.add(handler.handle); + transformedOutput = handler?.render(this, cell, output); + + output = transformedOutput; + (output).pickedMimeType = richestMimeType; + } + } + + return output; + }); + + return [diff.start, diff.deleteCount, outputs]; + }); + + this._proxy.$spliceNotebookCellOutputs(this.viewType, this.uri, cell.handle, outputDtos, Array.from(renderers)); + } + insertCell(index: number, cell: ExtHostCell) { this.cells.splice(index, 0, cell); @@ -252,7 +325,7 @@ export class ExtHostNotebookDocument implements vscode.NotebookDocument { let store = this._cellDisposableMapping.get(cell.handle)!; store.add(cell.onDidChangeOutputs((diffs) => { - this._proxy.$spliceNotebookCellOutputs(this.viewType, this.uri, cell.handle, diffs.map(diff => [diff.start, diff.deleteCount, diff.toInsert])); + this.eventuallyUpdateCellOutputs(cell, diffs); })); this.eventuallyUpdateCells([{ start: index, deleteCount: 0, toInsert: [cell] }]); -- GitLab