diff --git a/src/vs/workbench/api/common/extHostNotebookDocument.ts b/src/vs/workbench/api/common/extHostNotebookDocument.ts index 4866879fb1a..3fa9f2a53f5 100644 --- a/src/vs/workbench/api/common/extHostNotebookDocument.ts +++ b/src/vs/workbench/api/common/extHostNotebookDocument.ts @@ -231,7 +231,6 @@ export class ExtHostNotebookDocument { this._isDirty = isDirty; this.acceptDocumentPropertiesChanged({ metadata: newMetadata }); - const result = { notebook: this.apiNotebook, metadata: newMetadata, @@ -239,6 +238,9 @@ export class ExtHostNotebookDocument { contentChanges: [], }; + type RelaxedCellChange = Partial & { cell: vscode.NotebookCell }; + const relaxedCellChanges: RelaxedCellChange[] = []; + // -- apply change and populate content changes for (const rawEvent of event.rawEvents) { @@ -250,11 +252,11 @@ export class ExtHostNotebookDocument { } else if (rawEvent.kind === notebookCommon.NotebookCellsChangeType.Output) { this._setCellOutputs(rawEvent.index, rawEvent.outputs); - result.cellChanges.push({ cell: this._cells[rawEvent.index].apiCell, outputs: this._cells[rawEvent.index].apiCell.outputs, executionSummary: undefined, metadata: undefined }); + relaxedCellChanges.push({ cell: this._cells[rawEvent.index].apiCell, outputs: this._cells[rawEvent.index].apiCell.outputs }); } else if (rawEvent.kind === notebookCommon.NotebookCellsChangeType.OutputItem) { this._setCellOutputItems(rawEvent.index, rawEvent.outputId, rawEvent.append, rawEvent.outputItems); - result.cellChanges.push({ cell: this._cells[rawEvent.index].apiCell, outputs: this._cells[rawEvent.index].apiCell.outputs, executionSummary: undefined, metadata: undefined }); + relaxedCellChanges.push({ cell: this._cells[rawEvent.index].apiCell, outputs: this._cells[rawEvent.index].apiCell.outputs }); } else if (rawEvent.kind === notebookCommon.NotebookCellsChangeType.ChangeLanguage) { this._changeCellLanguage(rawEvent.index, rawEvent.language); @@ -262,26 +264,33 @@ export class ExtHostNotebookDocument { this._changeCellMime(rawEvent.index, rawEvent.mime); } else if (rawEvent.kind === notebookCommon.NotebookCellsChangeType.ChangeCellMetadata) { this._changeCellMetadata(rawEvent.index, rawEvent.metadata); - result.cellChanges.push({ cell: this._cells[rawEvent.index].apiCell, outputs: undefined, executionSummary: undefined, metadata: this._cells[rawEvent.index].apiCell.metadata }); + relaxedCellChanges.push({ cell: this._cells[rawEvent.index].apiCell, metadata: this._cells[rawEvent.index].apiCell.metadata }); } else if (rawEvent.kind === notebookCommon.NotebookCellsChangeType.ChangeCellInternalMetadata) { this._changeCellInternalMetadata(rawEvent.index, rawEvent.internalMetadata); - result.cellChanges.push({ cell: this._cells[rawEvent.index].apiCell, outputs: undefined, executionSummary: this._cells[rawEvent.index].apiCell.executionSummary, metadata: undefined }); + relaxedCellChanges.push({ cell: this._cells[rawEvent.index].apiCell, executionSummary: this._cells[rawEvent.index].apiCell.executionSummary }); } } // -- compact cellChanges const map = new Map(); - for (let i = 0; i < result.cellChanges.length; i++) { - let c = result.cellChanges[i]; - let existing = map.get(c.cell); + for (let i = 0; i < relaxedCellChanges.length; i++) { + const relaxedCellChange = relaxedCellChanges[i]; + const existing = map.get(relaxedCellChange.cell); if (existing === undefined) { - map.set(c.cell, i); + const newLen = result.cellChanges.push({ + executionSummary: undefined, + metadata: undefined, + outputs: undefined, + ...relaxedCellChange, + }); + map.set(relaxedCellChange.cell, newLen - 1); } else { - result.cellChanges[existing] = { ...result.cellChanges[existing], ...c }; - result.cellChanges.splice(i, 1); - i--; + result.cellChanges[existing] = { + ...result.cellChanges[existing], + ...relaxedCellChange + }; } } diff --git a/src/vs/workbench/api/test/browser/extHostNotebook.test.ts b/src/vs/workbench/api/test/browser/extHostNotebook.test.ts index 9930ad289b2..49bd53fa713 100644 --- a/src/vs/workbench/api/test/browser/extHostNotebook.test.ts +++ b/src/vs/workbench/api/test/browser/extHostNotebook.test.ts @@ -418,4 +418,55 @@ suite('NotebookCell#Document', function () { assert.strictEqual(first.document.languageId, 'fooLang'); assert.ok(removedDoc === addedDoc); }); + + test('onDidChangeNotebook-event, cell changes', async function () { + + const p = Event.toPromise(extHostNotebookDocuments.onDidChangeNotebookDocument); + + extHostNotebookDocuments.$acceptModelChanged(notebook.uri, new SerializableObjectWithBuffers({ + versionId: 12, rawEvents: [{ + kind: NotebookCellsChangeType.ChangeCellMetadata, + index: 0, + metadata: { foo: 1 } + }, { + kind: NotebookCellsChangeType.ChangeCellMetadata, + index: 1, + metadata: { foo: 2 }, + }, { + kind: NotebookCellsChangeType.Output, + index: 1, + outputs: [] + }] + }), false, undefined); + + + const event = await p; + + assert.strictEqual(event.notebook === notebook.apiNotebook, true); + assert.strictEqual(event.contentChanges.length, 0); + assert.strictEqual(event.cellChanges.length, 2); + + const [first, second] = event.cellChanges; + assert.deepStrictEqual(first.metadata, first.cell.metadata); + assert.deepStrictEqual(first.executionSummary, undefined); + assert.deepStrictEqual(first.outputs, undefined); + + assert.deepStrictEqual(second.outputs, second.cell.outputs); + assert.deepStrictEqual(second.metadata, second.cell.metadata); + assert.deepStrictEqual(second.executionSummary, undefined); + }); + + test('onDidChangeNotebook-event, notebook metadata', async function () { + + const p = Event.toPromise(extHostNotebookDocuments.onDidChangeNotebookDocument); + + extHostNotebookDocuments.$acceptModelChanged(notebook.uri, new SerializableObjectWithBuffers({ versionId: 12, rawEvents: [] }), false, { foo: 2 }); + + const event = await p; + + assert.strictEqual(event.notebook === notebook.apiNotebook, true); + assert.strictEqual(event.contentChanges.length, 0); + assert.strictEqual(event.cellChanges.length, 0); + assert.deepStrictEqual(event.metadata, { foo: 2 }); + }); });