Merge branch 'notebook/dev' into main
This commit is contained in:
commit
bffe6fdf12
11 changed files with 251 additions and 373 deletions
|
@ -21,6 +21,7 @@ suite('Notebook Editor', function () {
|
|||
};
|
||||
|
||||
const disposables: vscode.Disposable[] = [];
|
||||
const testDisposables: vscode.Disposable[] = [];
|
||||
|
||||
suiteTeardown(async function () {
|
||||
utils.assertNoRpc();
|
||||
|
@ -38,6 +39,10 @@ suite('Notebook Editor', function () {
|
|||
disposables.push(vscode.workspace.registerNotebookSerializer('notebook.nbdtest', contentSerializer));
|
||||
});
|
||||
|
||||
teardown(async function () {
|
||||
utils.disposeAll(testDisposables);
|
||||
testDisposables.length = 0;
|
||||
});
|
||||
|
||||
test('showNotebookDocment', async function () {
|
||||
|
||||
|
@ -74,4 +79,48 @@ suite('Notebook Editor', function () {
|
|||
assert.ok(await openedEditor);
|
||||
assert.strictEqual(editor.document.uri.toString(), resource.toString());
|
||||
});
|
||||
|
||||
test('Active/Visible Editor', async function () {
|
||||
const firstEditorOpen = utils.asPromise(vscode.window.onDidChangeActiveNotebookEditor);
|
||||
const resource = await utils.createRandomFile(undefined, undefined, '.nbdtest');
|
||||
const firstEditor = await vscode.window.showNotebookDocument(resource);
|
||||
await firstEditorOpen;
|
||||
assert.strictEqual(vscode.window.activeNotebookEditor, firstEditor);
|
||||
assert.strictEqual(vscode.window.visibleNotebookEditors.includes(firstEditor), true);
|
||||
|
||||
const secondEditor = await vscode.window.showNotebookDocument(resource, { viewColumn: vscode.ViewColumn.Beside });
|
||||
assert.strictEqual(secondEditor === vscode.window.activeNotebookEditor, true);
|
||||
assert.notStrictEqual(firstEditor, secondEditor);
|
||||
assert.strictEqual(vscode.window.visibleNotebookEditors.includes(secondEditor), true);
|
||||
assert.strictEqual(vscode.window.visibleNotebookEditors.includes(firstEditor), true);
|
||||
assert.strictEqual(vscode.window.visibleNotebookEditors.length, 2);
|
||||
});
|
||||
|
||||
test('Notebook Editor Event - onDidChangeVisibleNotebookEditors on open/close', async function () {
|
||||
const openedEditor = utils.asPromise(vscode.window.onDidChangeVisibleNotebookEditors);
|
||||
const resource = await utils.createRandomFile(undefined, undefined, '.nbdtest');
|
||||
await vscode.window.showNotebookDocument(resource);
|
||||
assert.ok(await openedEditor);
|
||||
|
||||
const firstEditorClose = utils.asPromise(vscode.window.onDidChangeVisibleNotebookEditors);
|
||||
await utils.closeAllEditors();
|
||||
await firstEditorClose;
|
||||
});
|
||||
|
||||
test('Notebook Editor Event - onDidChangeVisibleNotebookEditors on two editor groups', async function () {
|
||||
const resource = await utils.createRandomFile(undefined, undefined, '.nbdtest');
|
||||
let count = 0;
|
||||
testDisposables.push(vscode.window.onDidChangeVisibleNotebookEditors(() => {
|
||||
count = vscode.window.visibleNotebookEditors.length;
|
||||
}));
|
||||
|
||||
await vscode.window.showNotebookDocument(resource, { viewColumn: vscode.ViewColumn.Active });
|
||||
assert.strictEqual(count, 1);
|
||||
|
||||
await vscode.window.showNotebookDocument(resource, { viewColumn: vscode.ViewColumn.Beside });
|
||||
assert.strictEqual(count, 2);
|
||||
|
||||
await utils.closeAllEditors();
|
||||
assert.strictEqual(count, 0);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -56,18 +56,13 @@ class Kernel {
|
|||
}
|
||||
|
||||
protected async _runCell(cell: vscode.NotebookCell) {
|
||||
// create a single output with exec order 1 and output is plain/text
|
||||
// of either the cell itself or (iff empty) the cell's document's uri
|
||||
const task = this.controller.createNotebookCellExecution(cell);
|
||||
task.start();
|
||||
task.executionOrder = 1;
|
||||
if (cell.notebook.uri.path.endsWith('customRenderer.vsctestnb')) {
|
||||
await task.replaceOutput([new vscode.NotebookCellOutput([
|
||||
vscode.NotebookCellOutputItem.text('test', 'text/custom')
|
||||
])]);
|
||||
return;
|
||||
}
|
||||
|
||||
await task.replaceOutput([new vscode.NotebookCellOutput([
|
||||
vscode.NotebookCellOutputItem.text('my output', 'text/plain')
|
||||
vscode.NotebookCellOutputItem.text(cell.document.getText() || cell.document.uri.toString(), 'text/plain')
|
||||
])]);
|
||||
task.end(true);
|
||||
}
|
||||
|
@ -161,40 +156,12 @@ suite('Notebook API tests', function () {
|
|||
suiteDisposables.push(vscode.workspace.registerNotebookContentProvider('notebookCoreTest', apiTestContentProvider));
|
||||
});
|
||||
|
||||
let kernel1: Kernel;
|
||||
let kernel2: Kernel;
|
||||
let defaultKernel: Kernel;
|
||||
|
||||
setup(async function () {
|
||||
|
||||
kernel1 = new Kernel('mainKernel', 'Notebook Primary Test Kernel');
|
||||
|
||||
const listener = vscode.workspace.onDidOpenNotebookDocument(async notebook => {
|
||||
if (notebook.notebookType === kernel1.controller.notebookType) {
|
||||
await vscode.commands.executeCommand('notebook.selectKernel', {
|
||||
extension: 'vscode.vscode-api-tests',
|
||||
id: kernel1.controller.id
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
kernel2 = new class extends Kernel {
|
||||
constructor() {
|
||||
super('secondaryKernel', 'Notebook Secondary Test Kernel');
|
||||
this.controller.supportsExecutionOrder = false;
|
||||
}
|
||||
|
||||
override async _runCell(cell: vscode.NotebookCell) {
|
||||
const task = this.controller.createNotebookCellExecution(cell);
|
||||
task.start();
|
||||
await task.replaceOutput([new vscode.NotebookCellOutput([
|
||||
vscode.NotebookCellOutputItem.text('my second output', 'text/plain')
|
||||
])]);
|
||||
task.end(true);
|
||||
}
|
||||
};
|
||||
|
||||
testDisposables.push(kernel1.controller, listener, kernel2.controller);
|
||||
// there should be ONE default kernel in this suite
|
||||
defaultKernel = new Kernel('mainKernel', 'Notebook Default Kernel');
|
||||
testDisposables.push(defaultKernel.controller);
|
||||
await saveAllFilesAndCloseAll();
|
||||
});
|
||||
|
||||
|
@ -204,35 +171,6 @@ suite('Notebook API tests', function () {
|
|||
await saveAllFilesAndCloseAll();
|
||||
});
|
||||
|
||||
test('editor onDidChangeVisibleNotebookEditors-event', async function () {
|
||||
const resource = await createRandomNotebookFile();
|
||||
const firstEditorOpen = asPromise(vscode.window.onDidChangeVisibleNotebookEditors);
|
||||
await vscode.window.showNotebookDocument(resource);
|
||||
await firstEditorOpen;
|
||||
|
||||
const firstEditorClose = asPromise(vscode.window.onDidChangeVisibleNotebookEditors);
|
||||
await closeAllEditors();
|
||||
await firstEditorClose;
|
||||
});
|
||||
|
||||
test('editor onDidChangeVisibleNotebookEditors-event 2', async function () {
|
||||
const resource = await createRandomNotebookFile();
|
||||
let count = 0;
|
||||
const disposables: vscode.Disposable[] = [];
|
||||
disposables.push(vscode.window.onDidChangeVisibleNotebookEditors(() => {
|
||||
count = vscode.window.visibleNotebookEditors.length;
|
||||
}));
|
||||
|
||||
await vscode.window.showNotebookDocument(resource, { viewColumn: vscode.ViewColumn.Active });
|
||||
assert.strictEqual(count, 1);
|
||||
|
||||
await vscode.window.showNotebookDocument(resource, { viewColumn: vscode.ViewColumn.Beside });
|
||||
assert.strictEqual(count, 2);
|
||||
|
||||
await closeAllEditors();
|
||||
assert.strictEqual(count, 0);
|
||||
});
|
||||
|
||||
test('correct cell selection on undo/redo of cell creation', async function () {
|
||||
const notebook = await openRandomNotebookDocument();
|
||||
await vscode.window.showNotebookDocument(notebook);
|
||||
|
@ -252,23 +190,21 @@ suite('Notebook API tests', function () {
|
|||
assert.strictEqual(selectionRedo[0].end, 2);
|
||||
});
|
||||
|
||||
test('editor editing event 2', async function () {
|
||||
// const notebook = await openRandomNotebookDocument();
|
||||
// await vscode.window.showNotebookDocument(notebook);
|
||||
const resource = await createRandomNotebookFile();
|
||||
await vscode.commands.executeCommand('vscode.openWith', resource, 'notebookCoreTest');
|
||||
test('editor editing event', async function () {
|
||||
const notebook = await openRandomNotebookDocument();
|
||||
const editor = await vscode.window.showNotebookDocument(notebook);
|
||||
|
||||
const cellsChangeEvent = asPromise<vscode.NotebookCellsChangeEvent>(vscode.notebooks.onDidChangeNotebookCells);
|
||||
await vscode.commands.executeCommand('notebook.cell.insertCodeCellBelow');
|
||||
const cellChangeEventRet = await cellsChangeEvent;
|
||||
assert.strictEqual(cellChangeEventRet.document, vscode.window.activeNotebookEditor?.document);
|
||||
assert.strictEqual(cellChangeEventRet.document, editor.document);
|
||||
assert.strictEqual(cellChangeEventRet.changes.length, 1);
|
||||
assert.deepStrictEqual(cellChangeEventRet.changes[0], {
|
||||
start: 1,
|
||||
deletedCount: 0,
|
||||
deletedItems: [],
|
||||
items: [
|
||||
vscode.window.activeNotebookEditor!.document.cellAt(1)
|
||||
editor.document.cellAt(1)
|
||||
]
|
||||
});
|
||||
|
||||
|
@ -280,8 +216,8 @@ suite('Notebook API tests', function () {
|
|||
await vscode.commands.executeCommand('notebook.cell.execute');
|
||||
const cellOutputsAddedRet = await cellOutputChange;
|
||||
assert.deepStrictEqual(cellOutputsAddedRet, {
|
||||
document: vscode.window.activeNotebookEditor!.document,
|
||||
cells: [vscode.window.activeNotebookEditor!.document.cellAt(0)]
|
||||
document: editor.document,
|
||||
cells: [editor.document.cellAt(0)]
|
||||
});
|
||||
assert.strictEqual(cellOutputsAddedRet.cells[0].outputs.length, 1);
|
||||
|
||||
|
@ -289,8 +225,8 @@ suite('Notebook API tests', function () {
|
|||
await vscode.commands.executeCommand('notebook.cell.clearOutputs');
|
||||
const cellOutputsCleardRet = await cellOutputClear;
|
||||
assert.deepStrictEqual(cellOutputsCleardRet, {
|
||||
document: vscode.window.activeNotebookEditor!.document,
|
||||
cells: [vscode.window.activeNotebookEditor!.document.cellAt(0)]
|
||||
document: editor.document,
|
||||
cells: [editor.document.cellAt(0)]
|
||||
});
|
||||
assert.strictEqual(cellOutputsAddedRet.cells[0].outputs.length, 0);
|
||||
|
||||
|
@ -304,111 +240,45 @@ suite('Notebook API tests', function () {
|
|||
// });
|
||||
});
|
||||
|
||||
test('editor move cell event', async function () {
|
||||
const resource = await createRandomNotebookFile();
|
||||
await vscode.commands.executeCommand('vscode.openWith', resource, 'notebookCoreTest');
|
||||
|
||||
// const notebook = await openRandomNotebookDocument();
|
||||
// await vscode.window.showNotebookDocument(notebook);
|
||||
await vscode.commands.executeCommand('notebook.cell.insertCodeCellBelow');
|
||||
await vscode.commands.executeCommand('notebook.cell.insertCodeCellAbove');
|
||||
await vscode.commands.executeCommand('notebook.focusTop');
|
||||
|
||||
const activeCell = getFocusedCell(vscode.window.activeNotebookEditor);
|
||||
assert.strictEqual(vscode.window.activeNotebookEditor!.document.getCells().indexOf(activeCell!), 0);
|
||||
const moveChange = asPromise(vscode.notebooks.onDidChangeNotebookCells);
|
||||
await vscode.commands.executeCommand('notebook.cell.moveDown');
|
||||
await moveChange;
|
||||
await saveAllEditors();
|
||||
await closeAllEditors();
|
||||
|
||||
// await vscode.window.showNotebookDocument(notebook);
|
||||
await vscode.commands.executeCommand('vscode.openWith', resource, 'notebookCoreTest');
|
||||
const firstEditor = vscode.window.activeNotebookEditor;
|
||||
assert.strictEqual(firstEditor?.document.cellCount, 2);
|
||||
});
|
||||
|
||||
test('notebook editor active/visible', async function () {
|
||||
const resource = await createRandomNotebookFile();
|
||||
const firstEditor = await vscode.window.showNotebookDocument(resource, { viewColumn: vscode.ViewColumn.Active });
|
||||
assert.strictEqual(firstEditor === vscode.window.activeNotebookEditor, true);
|
||||
assert.strictEqual(vscode.window.visibleNotebookEditors.includes(firstEditor), true);
|
||||
|
||||
const secondEditor = await vscode.window.showNotebookDocument(resource, { viewColumn: vscode.ViewColumn.Beside });
|
||||
assert.strictEqual(secondEditor === vscode.window.activeNotebookEditor, true);
|
||||
|
||||
assert.notStrictEqual(firstEditor, secondEditor);
|
||||
assert.strictEqual(vscode.window.visibleNotebookEditors.includes(secondEditor), true);
|
||||
assert.strictEqual(vscode.window.visibleNotebookEditors.includes(firstEditor), true);
|
||||
assert.strictEqual(vscode.window.visibleNotebookEditors.length, 2);
|
||||
|
||||
const untitledEditorChange = asPromise(vscode.window.onDidChangeActiveNotebookEditor);
|
||||
await vscode.commands.executeCommand('workbench.action.files.newUntitledFile');
|
||||
await untitledEditorChange;
|
||||
assert.strictEqual(firstEditor && vscode.window.visibleNotebookEditors.indexOf(firstEditor) >= 0, true);
|
||||
assert.notStrictEqual(firstEditor, vscode.window.activeNotebookEditor);
|
||||
assert.strictEqual(secondEditor && vscode.window.visibleNotebookEditors.indexOf(secondEditor) < 0, true);
|
||||
assert.notStrictEqual(secondEditor, vscode.window.activeNotebookEditor);
|
||||
assert.strictEqual(vscode.window.visibleNotebookEditors.length, 1);
|
||||
|
||||
const activeEditorClose = asPromise(vscode.window.onDidChangeActiveNotebookEditor);
|
||||
await vscode.commands.executeCommand('workbench.action.closeActiveEditor');
|
||||
await activeEditorClose;
|
||||
assert.strictEqual(secondEditor, vscode.window.activeNotebookEditor);
|
||||
assert.strictEqual(vscode.window.visibleNotebookEditors.length, 2);
|
||||
assert.strictEqual(secondEditor && vscode.window.visibleNotebookEditors.indexOf(secondEditor) >= 0, true);
|
||||
});
|
||||
|
||||
test('notebook active editor change', async function () {
|
||||
const firstEditorOpen = asPromise(vscode.window.onDidChangeActiveNotebookEditor);
|
||||
const notebook = await openRandomNotebookDocument();
|
||||
await vscode.window.showNotebookDocument(notebook);
|
||||
await firstEditorOpen;
|
||||
|
||||
const firstEditorDeactivate = asPromise(vscode.window.onDidChangeActiveNotebookEditor);
|
||||
await vscode.commands.executeCommand('workbench.action.splitEditor');
|
||||
await firstEditorDeactivate;
|
||||
});
|
||||
|
||||
test('edit API batch edits', async function () {
|
||||
const resource = await createRandomNotebookFile();
|
||||
await vscode.commands.executeCommand('vscode.openWith', resource, 'notebookCoreTest');
|
||||
const notebook = await openRandomNotebookDocument();
|
||||
const editor = await vscode.window.showNotebookDocument(notebook);
|
||||
|
||||
const cellsChangeEvent = asPromise<vscode.NotebookCellsChangeEvent>(vscode.notebooks.onDidChangeNotebookCells);
|
||||
const cellMetadataChangeEvent = asPromise<vscode.NotebookCellMetadataChangeEvent>(vscode.notebooks.onDidChangeCellMetadata);
|
||||
const version = vscode.window.activeNotebookEditor!.document.version;
|
||||
await vscode.window.activeNotebookEditor!.edit(editBuilder => {
|
||||
const version = editor.document.version;
|
||||
await editor.edit(editBuilder => {
|
||||
editBuilder.replaceCells(1, 0, [{ kind: vscode.NotebookCellKind.Code, languageId: 'javascript', value: 'test 2', outputs: [], metadata: undefined }]);
|
||||
editBuilder.replaceCellMetadata(0, { inputCollapsed: false });
|
||||
});
|
||||
|
||||
await cellsChangeEvent;
|
||||
await cellMetadataChangeEvent;
|
||||
assert.strictEqual(version + 1, vscode.window.activeNotebookEditor!.document.version);
|
||||
assert.strictEqual(version + 1, editor.document.version);
|
||||
});
|
||||
|
||||
test('edit API batch edits undo/redo', async function () {
|
||||
const notebook = await openRandomNotebookDocument();
|
||||
await vscode.window.showNotebookDocument(notebook);
|
||||
const editor = await vscode.window.showNotebookDocument(notebook);
|
||||
|
||||
const cellsChangeEvent = asPromise<vscode.NotebookCellsChangeEvent>(vscode.notebooks.onDidChangeNotebookCells);
|
||||
const cellMetadataChangeEvent = asPromise<vscode.NotebookCellMetadataChangeEvent>(vscode.notebooks.onDidChangeCellMetadata);
|
||||
const version = vscode.window.activeNotebookEditor!.document.version;
|
||||
await vscode.window.activeNotebookEditor!.edit(editBuilder => {
|
||||
const version = editor.document.version;
|
||||
await editor.edit(editBuilder => {
|
||||
editBuilder.replaceCells(1, 0, [{ kind: vscode.NotebookCellKind.Code, languageId: 'javascript', value: 'test 2', outputs: [], metadata: undefined }]);
|
||||
editBuilder.replaceCellMetadata(0, { inputCollapsed: false });
|
||||
});
|
||||
|
||||
await cellsChangeEvent;
|
||||
await cellMetadataChangeEvent;
|
||||
assert.strictEqual(vscode.window.activeNotebookEditor!.document.cellCount, 3);
|
||||
assert.strictEqual(vscode.window.activeNotebookEditor!.document.cellAt(0)?.metadata.inputCollapsed, false);
|
||||
assert.strictEqual(version + 1, vscode.window.activeNotebookEditor!.document.version);
|
||||
assert.strictEqual(editor.document.cellCount, 3);
|
||||
assert.strictEqual(editor.document.cellAt(0)?.metadata.inputCollapsed, false);
|
||||
assert.strictEqual(version + 1, editor.document.version);
|
||||
|
||||
await vscode.commands.executeCommand('undo');
|
||||
assert.strictEqual(version + 2, vscode.window.activeNotebookEditor!.document.version);
|
||||
assert.strictEqual(vscode.window.activeNotebookEditor!.document.cellAt(0)?.metadata.inputCollapsed, undefined);
|
||||
assert.strictEqual(vscode.window.activeNotebookEditor!.document.cellCount, 2);
|
||||
assert.strictEqual(version + 2, editor.document.version);
|
||||
assert.strictEqual(editor.document.cellAt(0)?.metadata.inputCollapsed, undefined);
|
||||
assert.strictEqual(editor.document.cellCount, 2);
|
||||
});
|
||||
|
||||
test('#98841, initialzation should not emit cell change events.', async function () {
|
||||
|
@ -422,76 +292,61 @@ suite('Notebook API tests', function () {
|
|||
await vscode.window.showNotebookDocument(notebook);
|
||||
assert.strictEqual(count, 0);
|
||||
});
|
||||
// });
|
||||
|
||||
// suite('notebook workflow', () => {
|
||||
|
||||
test('notebook open', async function () {
|
||||
const notebook = await openRandomNotebookDocument();
|
||||
await vscode.window.showNotebookDocument(notebook);
|
||||
assert.strictEqual(vscode.window.activeNotebookEditor !== undefined, true, 'notebook first');
|
||||
assert.strictEqual(getFocusedCell(vscode.window.activeNotebookEditor)?.document.getText(), 'test');
|
||||
assert.strictEqual(getFocusedCell(vscode.window.activeNotebookEditor)?.document.languageId, 'typescript');
|
||||
const editor = await vscode.window.showNotebookDocument(notebook);
|
||||
assert.strictEqual(vscode.window.activeNotebookEditor === editor, true, 'notebook first');
|
||||
assert.strictEqual(getFocusedCell(editor)?.document.getText(), 'test');
|
||||
assert.strictEqual(getFocusedCell(editor)?.document.languageId, 'typescript');
|
||||
|
||||
const secondCell = vscode.window.activeNotebookEditor!.document.cellAt(1);
|
||||
assert.strictEqual(secondCell!.outputs.length, 1);
|
||||
assert.deepStrictEqual(secondCell!.outputs[0].metadata, { testOutputMetadata: true, ['text/plain']: { testOutputItemMetadata: true } });
|
||||
assert.strictEqual(secondCell!.outputs[0].items.length, 1);
|
||||
assert.strictEqual(secondCell!.outputs[0].items[0].mime, 'text/plain');
|
||||
assert.strictEqual(new TextDecoder().decode(secondCell!.outputs[0].items[0].data), 'Hello World');
|
||||
assert.strictEqual(secondCell!.executionSummary?.executionOrder, 5);
|
||||
assert.strictEqual(secondCell!.executionSummary?.success, true);
|
||||
|
||||
await vscode.commands.executeCommand('notebook.cell.insertCodeCellBelow');
|
||||
assert.strictEqual(getFocusedCell(vscode.window.activeNotebookEditor)?.document.getText(), '');
|
||||
|
||||
await vscode.commands.executeCommand('notebook.cell.insertCodeCellAbove');
|
||||
const activeCell = getFocusedCell(vscode.window.activeNotebookEditor);
|
||||
assert.notStrictEqual(getFocusedCell(vscode.window.activeNotebookEditor), undefined);
|
||||
assert.strictEqual(activeCell!.document.getText(), '');
|
||||
assert.strictEqual(vscode.window.activeNotebookEditor!.document.cellCount, 4);
|
||||
assert.strictEqual(vscode.window.activeNotebookEditor!.document.getCells().indexOf(activeCell!), 1);
|
||||
|
||||
await vscode.commands.executeCommand('workbench.action.files.save');
|
||||
await vscode.commands.executeCommand('workbench.action.closeActiveEditor');
|
||||
const secondCell = editor.document.cellAt(1);
|
||||
assert.strictEqual(secondCell.outputs.length, 1);
|
||||
assert.deepStrictEqual(secondCell.outputs[0].metadata, { testOutputMetadata: true, ['text/plain']: { testOutputItemMetadata: true } });
|
||||
assert.strictEqual(secondCell.outputs[0].items.length, 1);
|
||||
assert.strictEqual(secondCell.outputs[0].items[0].mime, 'text/plain');
|
||||
assert.strictEqual(new TextDecoder().decode(secondCell.outputs[0].items[0].data), 'Hello World');
|
||||
assert.strictEqual(secondCell.executionSummary?.executionOrder, 5);
|
||||
assert.strictEqual(secondCell.executionSummary?.success, true);
|
||||
});
|
||||
|
||||
test('notebook cell actions', async function () {
|
||||
const notebook = await openRandomNotebookDocument();
|
||||
await vscode.window.showNotebookDocument(notebook);
|
||||
const editor = await vscode.window.showNotebookDocument(notebook);
|
||||
assert.strictEqual(vscode.window.activeNotebookEditor !== undefined, true, 'notebook first');
|
||||
assert.strictEqual(getFocusedCell(vscode.window.activeNotebookEditor)?.document.getText(), 'test');
|
||||
assert.strictEqual(getFocusedCell(vscode.window.activeNotebookEditor)?.document.languageId, 'typescript');
|
||||
assert.strictEqual(vscode.window.activeNotebookEditor === editor, true, 'notebook first');
|
||||
assert.strictEqual(getFocusedCell(editor)?.document.getText(), 'test');
|
||||
assert.strictEqual(getFocusedCell(editor)?.document.languageId, 'typescript');
|
||||
|
||||
// ---- insert cell below and focus ---- //
|
||||
await vscode.commands.executeCommand('notebook.cell.insertCodeCellBelow');
|
||||
assert.strictEqual(getFocusedCell(vscode.window.activeNotebookEditor)?.document.getText(), '');
|
||||
assert.strictEqual(getFocusedCell(editor)?.document.getText(), '');
|
||||
|
||||
// ---- insert cell above and focus ---- //
|
||||
await vscode.commands.executeCommand('notebook.cell.insertCodeCellAbove');
|
||||
let activeCell = getFocusedCell(vscode.window.activeNotebookEditor);
|
||||
assert.notStrictEqual(getFocusedCell(vscode.window.activeNotebookEditor), undefined);
|
||||
let activeCell = getFocusedCell(editor);
|
||||
assert.notStrictEqual(getFocusedCell(editor), undefined);
|
||||
assert.strictEqual(activeCell!.document.getText(), '');
|
||||
assert.strictEqual(vscode.window.activeNotebookEditor!.document.cellCount, 4);
|
||||
assert.strictEqual(vscode.window.activeNotebookEditor!.document.getCells().indexOf(activeCell!), 1);
|
||||
assert.strictEqual(editor.document.cellCount, 4);
|
||||
assert.strictEqual(editor.document.getCells().indexOf(activeCell!), 1);
|
||||
|
||||
// ---- focus bottom ---- //
|
||||
await vscode.commands.executeCommand('notebook.focusBottom');
|
||||
activeCell = getFocusedCell(vscode.window.activeNotebookEditor);
|
||||
assert.strictEqual(vscode.window.activeNotebookEditor!.document.getCells().indexOf(activeCell!), 3);
|
||||
activeCell = getFocusedCell(editor);
|
||||
assert.strictEqual(editor.document.getCells().indexOf(activeCell!), 3);
|
||||
|
||||
// ---- focus top and then copy down ---- //
|
||||
await vscode.commands.executeCommand('notebook.focusTop');
|
||||
activeCell = getFocusedCell(vscode.window.activeNotebookEditor);
|
||||
assert.strictEqual(vscode.window.activeNotebookEditor!.document.getCells().indexOf(activeCell!), 0);
|
||||
activeCell = getFocusedCell(editor);
|
||||
assert.strictEqual(editor.document.getCells().indexOf(activeCell!), 0);
|
||||
|
||||
await vscode.commands.executeCommand('notebook.cell.copyDown');
|
||||
activeCell = getFocusedCell(vscode.window.activeNotebookEditor);
|
||||
assert.strictEqual(vscode.window.activeNotebookEditor!.document.getCells().indexOf(activeCell!), 1);
|
||||
activeCell = getFocusedCell(editor);
|
||||
assert.strictEqual(editor.document.getCells().indexOf(activeCell!), 1);
|
||||
assert.strictEqual(activeCell?.document.getText(), 'test');
|
||||
|
||||
{
|
||||
const focusedCell = getFocusedCell(vscode.window.activeNotebookEditor);
|
||||
const focusedCell = getFocusedCell(editor);
|
||||
assert.strictEqual(focusedCell !== undefined, true);
|
||||
// delete focused cell
|
||||
const edit = new vscode.WorkspaceEdit();
|
||||
|
@ -499,45 +354,44 @@ suite('Notebook API tests', function () {
|
|||
await vscode.workspace.applyEdit(edit);
|
||||
}
|
||||
|
||||
activeCell = getFocusedCell(vscode.window.activeNotebookEditor);
|
||||
assert.strictEqual(vscode.window.activeNotebookEditor!.document.getCells().indexOf(activeCell!), 1);
|
||||
activeCell = getFocusedCell(editor);
|
||||
assert.strictEqual(editor.document.getCells().indexOf(activeCell!), 1);
|
||||
assert.strictEqual(activeCell?.document.getText(), '');
|
||||
|
||||
// ---- focus top and then copy up ---- //
|
||||
await vscode.commands.executeCommand('notebook.focusTop');
|
||||
await vscode.commands.executeCommand('notebook.cell.copyUp');
|
||||
assert.strictEqual(vscode.window.activeNotebookEditor!.document.cellCount, 5);
|
||||
assert.strictEqual(vscode.window.activeNotebookEditor!.document.cellAt(0).document.getText(), 'test');
|
||||
assert.strictEqual(vscode.window.activeNotebookEditor!.document.cellAt(1).document.getText(), 'test');
|
||||
assert.strictEqual(vscode.window.activeNotebookEditor!.document.cellAt(2).document.getText(), '');
|
||||
assert.strictEqual(vscode.window.activeNotebookEditor!.document.cellAt(3).document.getText(), '');
|
||||
activeCell = getFocusedCell(vscode.window.activeNotebookEditor);
|
||||
assert.strictEqual(vscode.window.activeNotebookEditor!.document.getCells().indexOf(activeCell!), 0);
|
||||
assert.strictEqual(editor.document.cellCount, 5);
|
||||
assert.strictEqual(editor.document.cellAt(0).document.getText(), 'test');
|
||||
assert.strictEqual(editor.document.cellAt(1).document.getText(), 'test');
|
||||
assert.strictEqual(editor.document.cellAt(2).document.getText(), '');
|
||||
assert.strictEqual(editor.document.cellAt(3).document.getText(), '');
|
||||
activeCell = getFocusedCell(editor);
|
||||
assert.strictEqual(editor.document.getCells().indexOf(activeCell!), 0);
|
||||
|
||||
|
||||
// ---- move up and down ---- //
|
||||
|
||||
await vscode.commands.executeCommand('notebook.cell.moveDown');
|
||||
assert.strictEqual(vscode.window.activeNotebookEditor!.document.getCells().indexOf(getFocusedCell(vscode.window.activeNotebookEditor)!), 1,
|
||||
`first move down, active cell ${getFocusedCell(vscode.window.activeNotebookEditor)!.document.uri.toString()}, ${getFocusedCell(vscode.window.activeNotebookEditor)!.document.getText()}`);
|
||||
assert.strictEqual(editor.document.getCells().indexOf(getFocusedCell(editor)!), 1,
|
||||
`first move down, active cell ${getFocusedCell(editor)!.document.uri.toString()}, ${getFocusedCell(editor)!.document.getText()}`);
|
||||
|
||||
await vscode.commands.executeCommand('workbench.action.files.save');
|
||||
await vscode.commands.executeCommand('workbench.action.closeActiveEditor');
|
||||
});
|
||||
|
||||
test('move cells will not recreate cells in ExtHost', async function () {
|
||||
test('editor move command - event and move cells will not recreate cells in ExtHost (#98126)', async function () {
|
||||
const notebook = await openRandomNotebookDocument();
|
||||
await vscode.window.showNotebookDocument(notebook);
|
||||
await vscode.commands.executeCommand('notebook.cell.insertCodeCellBelow');
|
||||
await vscode.commands.executeCommand('notebook.cell.insertCodeCellAbove');
|
||||
await vscode.commands.executeCommand('notebook.focusTop');
|
||||
const editor = await vscode.window.showNotebookDocument(notebook);
|
||||
|
||||
const activeCell = getFocusedCell(vscode.window.activeNotebookEditor);
|
||||
assert.strictEqual(vscode.window.activeNotebookEditor!.document.getCells().indexOf(activeCell!), 0);
|
||||
await vscode.commands.executeCommand('notebook.cell.moveDown');
|
||||
const activeCell = getFocusedCell(editor);
|
||||
assert.strictEqual(activeCell?.index, 0);
|
||||
const moveChange = asPromise(vscode.notebooks.onDidChangeNotebookCells);
|
||||
await vscode.commands.executeCommand('notebook.cell.moveDown');
|
||||
assert.ok(await moveChange);
|
||||
|
||||
const newActiveCell = getFocusedCell(vscode.window.activeNotebookEditor);
|
||||
const newActiveCell = getFocusedCell(editor);
|
||||
assert.strictEqual(newActiveCell?.index, 1);
|
||||
assert.deepStrictEqual(activeCell, newActiveCell);
|
||||
});
|
||||
|
||||
|
@ -674,18 +528,35 @@ suite('Notebook API tests', function () {
|
|||
|
||||
const cell = editor.document.cellAt(0);
|
||||
|
||||
const alternativeKernel = new class extends Kernel {
|
||||
constructor() {
|
||||
super('secondaryKernel', 'Notebook Secondary Test Kernel');
|
||||
this.controller.supportsExecutionOrder = false;
|
||||
}
|
||||
|
||||
override async _runCell(cell: vscode.NotebookCell) {
|
||||
const task = this.controller.createNotebookCellExecution(cell);
|
||||
task.start();
|
||||
await task.replaceOutput([new vscode.NotebookCellOutput([
|
||||
vscode.NotebookCellOutputItem.text('my second output', 'text/plain')
|
||||
])]);
|
||||
task.end(true);
|
||||
}
|
||||
};
|
||||
testDisposables.push(alternativeKernel.controller);
|
||||
|
||||
await withEvent<vscode.NotebookCellOutputsChangeEvent>(vscode.notebooks.onDidChangeCellOutputs, async (event) => {
|
||||
await assertKernel(kernel1, notebook);
|
||||
await assertKernel(defaultKernel, notebook);
|
||||
await vscode.commands.executeCommand('notebook.cell.execute');
|
||||
await event;
|
||||
assert.strictEqual(cell.outputs.length, 1, 'should execute'); // runnable, it worked
|
||||
assert.strictEqual(cell.outputs[0].items.length, 1);
|
||||
assert.strictEqual(cell.outputs[0].items[0].mime, 'text/plain');
|
||||
assert.deepStrictEqual(new TextDecoder().decode(cell.outputs[0].items[0].data), 'my output');
|
||||
assert.deepStrictEqual(new TextDecoder().decode(cell.outputs[0].items[0].data), cell.document.getText());
|
||||
});
|
||||
|
||||
await withEvent<vscode.NotebookCellOutputsChangeEvent>(vscode.notebooks.onDidChangeCellOutputs, async (event) => {
|
||||
await assertKernel(kernel2, notebook);
|
||||
await assertKernel(alternativeKernel, notebook);
|
||||
await vscode.commands.executeCommand('notebook.cell.execute');
|
||||
await event;
|
||||
assert.strictEqual(cell.outputs.length, 1, 'should execute'); // runnable, it worked
|
||||
|
@ -1134,18 +1005,31 @@ suite('Notebook API tests', function () {
|
|||
assert.strictEqual(cell.executionSummary?.timing?.endTime, 20);
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
suite('statusbar', () => {
|
||||
suite('statusbar', () => {
|
||||
const emitter = new vscode.EventEmitter<vscode.NotebookCell>();
|
||||
const onDidCallProvide = emitter.event;
|
||||
const suiteDisposables: vscode.Disposable[] = [];
|
||||
suiteTeardown(async function () {
|
||||
assertNoRpc();
|
||||
|
||||
await revertAllDirty();
|
||||
await closeAllEditors();
|
||||
|
||||
disposeAll(suiteDisposables);
|
||||
suiteDisposables.length = 0;
|
||||
});
|
||||
|
||||
suiteSetup(() => {
|
||||
vscode.notebooks.registerNotebookCellStatusBarItemProvider('notebookCoreTest', {
|
||||
suiteDisposables.push(vscode.notebooks.registerNotebookCellStatusBarItemProvider('notebookCoreTest', {
|
||||
async provideCellStatusBarItems(cell: vscode.NotebookCell, _token: vscode.CancellationToken): Promise<vscode.NotebookCellStatusBarItem[]> {
|
||||
emitter.fire(cell);
|
||||
return [];
|
||||
}
|
||||
});
|
||||
}));
|
||||
|
||||
suiteDisposables.push(vscode.workspace.registerNotebookContentProvider('notebookCoreTest', apiTestContentProvider));
|
||||
});
|
||||
|
||||
test('provideCellStatusBarItems called on metadata change', async function () {
|
||||
|
@ -1159,49 +1043,6 @@ suite('Notebook API tests', function () {
|
|||
vscode.workspace.applyEdit(edit);
|
||||
await provideCalled;
|
||||
});
|
||||
});
|
||||
|
||||
// });
|
||||
|
||||
// suite('webview', () => {
|
||||
// for web, `asWebUri` gets `https`?
|
||||
// test('asWebviewUri', async function () {
|
||||
// if (vscode.env.uiKind === vscode.UIKind.Web) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
// const resource = await createRandomNotebookFile();
|
||||
// await vscode.commands.executeCommand('vscode.openWith', resource, 'notebookCoreTest');
|
||||
// assert.strictEqual(vscode.window.activeNotebookEditor !== undefined, true, 'notebook first');
|
||||
// const uri = vscode.window.activeNotebookEditor!.asWebviewUri(vscode.Uri.file('./hello.png'));
|
||||
// assert.strictEqual(uri.scheme, 'vscode-webview-resource');
|
||||
// await closeAllEditors();
|
||||
// });
|
||||
|
||||
|
||||
// 404 on web
|
||||
// test('custom renderer message', async function () {
|
||||
// if (vscode.env.uiKind === vscode.UIKind.Web) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
// const resource = vscode.Uri.file(join(vscode.workspace.rootPath || '', './customRenderer.vsctestnb'));
|
||||
// await vscode.commands.executeCommand('vscode.openWith', resource, 'notebookCoreTest');
|
||||
|
||||
// const editor = vscode.window.activeNotebookEditor;
|
||||
// const promise = new Promise(resolve => {
|
||||
// const messageEmitter = editor?.onDidReceiveMessage(e => {
|
||||
// if (e.type === 'custom_renderer_initialize') {
|
||||
// resolve();
|
||||
// messageEmitter?.dispose();
|
||||
// }
|
||||
// });
|
||||
// });
|
||||
|
||||
// await vscode.commands.executeCommand('notebook.cell.execute');
|
||||
// await promise;
|
||||
// await closeAllEditors();
|
||||
// });
|
||||
});
|
||||
|
||||
suite('Notebook API tests (metadata)', function () {
|
||||
|
|
|
@ -1874,14 +1874,18 @@ registerAction2(class NotebookConfigureLayoutAction extends Action2 {
|
|||
group: 'notebookLayout',
|
||||
when: ContextKeyExpr.and(
|
||||
NOTEBOOK_IS_ACTIVE_EDITOR,
|
||||
ContextKeyExpr.notEquals('config.notebook.globalToolbar', true)
|
||||
ContextKeyExpr.notEquals('config.notebook.globalToolbar', true),
|
||||
ContextKeyExpr.equals('config.notebook.experimental.openGettingStarted', true)
|
||||
),
|
||||
order: 0
|
||||
},
|
||||
{
|
||||
id: MenuId.NotebookToolbar,
|
||||
group: 'notebookLayout',
|
||||
when: ContextKeyExpr.equals('config.notebook.globalToolbar', true),
|
||||
when: ContextKeyExpr.and(
|
||||
ContextKeyExpr.equals('config.notebook.globalToolbar', true),
|
||||
ContextKeyExpr.equals('config.notebook.experimental.openGettingStarted', true)
|
||||
),
|
||||
order: 0
|
||||
}
|
||||
]
|
||||
|
|
|
@ -65,7 +65,7 @@ class NotebookViewportContribution extends Disposable implements INotebookEditor
|
|||
if (pickedMimeTypeRenderer.rendererId === BUILTIN_RENDERER_ID) {
|
||||
const renderer = this._notebookEditor.getOutputRenderer().getContribution(pickedMimeTypeRenderer.mimeType);
|
||||
if (renderer?.getType() === RenderOutputType.Html) {
|
||||
const renderResult = renderer.render(output, output.model.outputs.filter(op => op.mime === pickedMimeTypeRenderer.mimeType), DOM.$(''), this._notebookEditor.viewModel.uri) as IInsetRenderOutput;
|
||||
const renderResult = renderer.render(output, output.model.outputs.filter(op => op.mime === pickedMimeTypeRenderer.mimeType)[0], DOM.$(''), this._notebookEditor.viewModel.uri) as IInsetRenderOutput;
|
||||
this._notebookEditor.createOutput(viewCell, renderResult, 0);
|
||||
}
|
||||
return;
|
||||
|
|
|
@ -764,7 +764,7 @@ export interface IOutputTransformContribution {
|
|||
* This call is allowed to have side effects, such as placing output
|
||||
* directly into the container element.
|
||||
*/
|
||||
render(output: ICellOutputViewModel, items: IOutputItemDto[], container: HTMLElement, notebookUri: URI): IRenderOutput;
|
||||
render(output: ICellOutputViewModel, item: IOutputItemDto, container: HTMLElement, notebookUri: URI): IRenderOutput;
|
||||
}
|
||||
|
||||
export interface CellFindMatch {
|
||||
|
|
|
@ -68,6 +68,6 @@ export class OutputRenderer {
|
|||
return this._renderMessage(container, localize('empty', "Cell has no output"));
|
||||
}
|
||||
|
||||
return renderer.render(viewModel, [first], container, notebookUri);
|
||||
return renderer.render(viewModel, first, container, notebookUri);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,13 +39,11 @@ class JavaScriptRendererContrib extends Disposable implements IOutputRendererCon
|
|||
super();
|
||||
}
|
||||
|
||||
render(output: ICellOutputViewModel, items: IOutputItemDto[], container: HTMLElement, notebookUri: URI): IRenderOutput {
|
||||
let scriptVal = '';
|
||||
items.forEach(item => {
|
||||
const str = getStringValue(item);
|
||||
scriptVal += `<script type="application/javascript">${str}</script>`;
|
||||
render(output: ICellOutputViewModel, item: IOutputItemDto, container: HTMLElement, notebookUri: URI): IRenderOutput {
|
||||
|
||||
const str = getStringValue(item);
|
||||
const scriptVal = `<script type="application/javascript">${str}</script>`;
|
||||
|
||||
});
|
||||
return {
|
||||
type: RenderOutputType.Html,
|
||||
source: output,
|
||||
|
@ -72,8 +70,8 @@ class CodeRendererContrib extends Disposable implements IOutputRendererContribut
|
|||
super();
|
||||
}
|
||||
|
||||
render(output: ICellOutputViewModel, items: IOutputItemDto[], container: HTMLElement): IRenderOutput {
|
||||
const value = items.map(getStringValue).join('');
|
||||
render(output: ICellOutputViewModel, item: IOutputItemDto, container: HTMLElement): IRenderOutput {
|
||||
const value = getStringValue(item);
|
||||
return this._render(output, container, value, 'javascript');
|
||||
}
|
||||
|
||||
|
@ -106,8 +104,8 @@ class JSONRendererContrib extends CodeRendererContrib {
|
|||
return ['application/json'];
|
||||
}
|
||||
|
||||
override render(output: ICellOutputViewModel, items: IOutputItemDto[], container: HTMLElement): IRenderOutput {
|
||||
const str = items.map(getStringValue).join('');
|
||||
override render(output: ICellOutputViewModel, item: IOutputItemDto, container: HTMLElement): IRenderOutput {
|
||||
const str = getStringValue(item);
|
||||
return this._render(output, container, str, 'jsonc');
|
||||
}
|
||||
}
|
||||
|
@ -130,15 +128,13 @@ class StreamRendererContrib extends Disposable implements IOutputRendererContrib
|
|||
super();
|
||||
}
|
||||
|
||||
render(output: ICellOutputViewModel, items: IOutputItemDto[], container: HTMLElement, notebookUri: URI): IRenderOutput {
|
||||
render(output: ICellOutputViewModel, item: IOutputItemDto, container: HTMLElement, notebookUri: URI): IRenderOutput {
|
||||
const linkDetector = this.instantiationService.createInstance(LinkDetector);
|
||||
|
||||
items.forEach(item => {
|
||||
const text = getStringValue(item);
|
||||
const contentNode = DOM.$('span.output-stream');
|
||||
truncatedArrayOfString(notebookUri!, output.cellViewModel, contentNode, [text], linkDetector, this.openerService, this.themeService);
|
||||
truncatedArrayOfString(notebookUri, output.cellViewModel, contentNode, [text], linkDetector, this.openerService, this.themeService);
|
||||
container.appendChild(contentNode);
|
||||
});
|
||||
|
||||
return { type: RenderOutputType.Mainframe };
|
||||
}
|
||||
|
@ -153,8 +149,8 @@ class StderrRendererContrib extends StreamRendererContrib {
|
|||
return ['application/vnd.code.notebook.stderr', 'application/x.notebook.stderr'];
|
||||
}
|
||||
|
||||
override render(output: ICellOutputViewModel, items: IOutputItemDto[], container: HTMLElement, notebookUri: URI): IRenderOutput {
|
||||
const result = super.render(output, items, container, notebookUri);
|
||||
override render(output: ICellOutputViewModel, item: IOutputItemDto, container: HTMLElement, notebookUri: URI): IRenderOutput {
|
||||
const result = super.render(output, item, container, notebookUri);
|
||||
container.classList.add('error');
|
||||
return result;
|
||||
}
|
||||
|
@ -181,18 +177,18 @@ class JSErrorRendererContrib implements IOutputRendererContribution {
|
|||
return ['application/vnd.code.notebook.error'];
|
||||
}
|
||||
|
||||
render(_output: ICellOutputViewModel, items: IOutputItemDto[], container: HTMLElement, _notebookUri: URI): IRenderOutput {
|
||||
render(_output: ICellOutputViewModel, item: IOutputItemDto, container: HTMLElement, _notebookUri: URI): IRenderOutput {
|
||||
const linkDetector = this._instantiationService.createInstance(LinkDetector);
|
||||
|
||||
type ErrorLike = Partial<Error>;
|
||||
|
||||
for (let item of items) {
|
||||
|
||||
let err: ErrorLike;
|
||||
try {
|
||||
err = <ErrorLike>JSON.parse(getStringValue(item));
|
||||
} catch (e) {
|
||||
this._logService.warn('INVALID output item (failed to parse)', e);
|
||||
continue;
|
||||
return { type: RenderOutputType.Mainframe };
|
||||
}
|
||||
|
||||
const header = document.createElement('div');
|
||||
|
@ -208,7 +204,6 @@ class JSErrorRendererContrib implements IOutputRendererContribution {
|
|||
}
|
||||
container.appendChild(stack);
|
||||
container.classList.add('error');
|
||||
}
|
||||
|
||||
return { type: RenderOutputType.Mainframe };
|
||||
}
|
||||
|
@ -232,12 +227,12 @@ class PlainTextRendererContrib extends Disposable implements IOutputRendererCont
|
|||
super();
|
||||
}
|
||||
|
||||
render(output: ICellOutputViewModel, items: IOutputItemDto[], container: HTMLElement, notebookUri: URI): IRenderOutput {
|
||||
render(output: ICellOutputViewModel, item: IOutputItemDto, container: HTMLElement, notebookUri: URI): IRenderOutput {
|
||||
const linkDetector = this.instantiationService.createInstance(LinkDetector);
|
||||
|
||||
const str = items.map(getStringValue);
|
||||
const str = getStringValue(item);
|
||||
const contentNode = DOM.$('.output-plaintext');
|
||||
truncatedArrayOfString(notebookUri!, output.cellViewModel, contentNode, str, linkDetector, this.openerService, this.themeService);
|
||||
truncatedArrayOfString(notebookUri, output.cellViewModel, contentNode, [str], linkDetector, this.openerService, this.themeService);
|
||||
container.appendChild(contentNode);
|
||||
|
||||
return { type: RenderOutputType.Mainframe, supportAppend: true };
|
||||
|
@ -259,8 +254,8 @@ class HTMLRendererContrib extends Disposable implements IOutputRendererContribut
|
|||
super();
|
||||
}
|
||||
|
||||
render(output: ICellOutputViewModel, items: IOutputItemDto[], container: HTMLElement, notebookUri: URI): IRenderOutput {
|
||||
const str = items.map(getStringValue).join('');
|
||||
render(output: ICellOutputViewModel, item: IOutputItemDto, container: HTMLElement, notebookUri: URI): IRenderOutput {
|
||||
const str = getStringValue(item);
|
||||
return {
|
||||
type: RenderOutputType.Html,
|
||||
source: output,
|
||||
|
@ -285,16 +280,14 @@ class MdRendererContrib extends Disposable implements IOutputRendererContributio
|
|||
super();
|
||||
}
|
||||
|
||||
render(output: ICellOutputViewModel, items: IOutputItemDto[], container: HTMLElement, notebookUri: URI): IRenderOutput {
|
||||
render(output: ICellOutputViewModel, item: IOutputItemDto, container: HTMLElement, notebookUri: URI): IRenderOutput {
|
||||
const disposable = new DisposableStore();
|
||||
for (let item of items) {
|
||||
const str = getStringValue(item);
|
||||
const mdOutput = document.createElement('div');
|
||||
const mdRenderer = this.instantiationService.createInstance(MarkdownRenderer, { baseUrl: dirname(notebookUri) });
|
||||
mdOutput.appendChild(mdRenderer.render({ value: str, isTrusted: true, supportThemeIcons: true }, undefined, { gfm: true }).element);
|
||||
container.appendChild(mdOutput);
|
||||
disposable.add(mdRenderer);
|
||||
}
|
||||
return { type: RenderOutputType.Mainframe, disposable };
|
||||
}
|
||||
}
|
||||
|
@ -314,11 +307,9 @@ class ImgRendererContrib extends Disposable implements IOutputRendererContributi
|
|||
super();
|
||||
}
|
||||
|
||||
render(output: ICellOutputViewModel, items: IOutputItemDto[], container: HTMLElement, notebookUri: URI): IRenderOutput {
|
||||
render(output: ICellOutputViewModel, item: IOutputItemDto, container: HTMLElement, notebookUri: URI): IRenderOutput {
|
||||
const disposable = new DisposableStore();
|
||||
|
||||
for (let item of items) {
|
||||
|
||||
const bytes = new Uint8Array(item.valueBytes);
|
||||
const blob = new Blob([bytes], { type: item.mime });
|
||||
const src = URL.createObjectURL(blob);
|
||||
|
@ -330,7 +321,7 @@ class ImgRendererContrib extends Disposable implements IOutputRendererContributi
|
|||
display.classList.add('display');
|
||||
display.appendChild(image);
|
||||
container.appendChild(display);
|
||||
}
|
||||
|
||||
return { type: RenderOutputType.Mainframe, disposable };
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ import { Emitter, Event } from 'vs/base/common/event';
|
|||
import { Disposable, dispose, IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { NotebookCellTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookCellTextModel';
|
||||
import { INotebookTextModel, NotebookCellOutputsSplice, NotebookDocumentMetadata, NotebookCellMetadata, ICellEditOperation, CellEditType, CellUri, notebookDocumentMetadataDefaults, diff, NotebookCellsChangeType, ICellDto2, TransientOptions, NotebookTextModelChangedEvent, NotebookRawContentEvent, IOutputDto, ICellOutput, IOutputItemDto, ISelectionState, NullablePartialNotebookCellMetadata, NotebookCellInternalMetadata, NullablePartialNotebookCellInternalMetadata } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
import { INotebookTextModel, NotebookCellOutputsSplice, NotebookDocumentMetadata, NotebookCellMetadata, ICellEditOperation, CellEditType, CellUri, diff, NotebookCellsChangeType, ICellDto2, TransientOptions, NotebookTextModelChangedEvent, NotebookRawContentEvent, IOutputDto, ICellOutput, IOutputItemDto, ISelectionState, NullablePartialNotebookCellMetadata, NotebookCellInternalMetadata, NullablePartialNotebookCellInternalMetadata } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
import { IUndoRedoService, UndoRedoElementType, IUndoRedoElement, IResourceUndoRedoElement, UndoRedoGroup, IWorkspaceUndoRedoElement } from 'vs/platform/undoRedo/common/undoRedo';
|
||||
import { MoveCellEdit, SpliceCellsEdit, CellMetadataEdit } from 'vs/workbench/contrib/notebook/common/model/cellEdit';
|
||||
import { ISequence, LcsDiff } from 'vs/base/common/diff/diff';
|
||||
|
@ -197,7 +197,7 @@ export class NotebookTextModel extends Disposable implements INotebookTextModel
|
|||
private _cellListeners: Map<number, IDisposable> = new Map();
|
||||
private _cells: NotebookCellTextModel[] = [];
|
||||
|
||||
metadata: NotebookDocumentMetadata = notebookDocumentMetadataDefaults;
|
||||
metadata: NotebookDocumentMetadata = {};
|
||||
transientOptions: TransientOptions = { transientCellMetadata: {}, transientDocumentMetadata: {}, transientOutputs: false };
|
||||
private _versionId = 0;
|
||||
|
||||
|
|
|
@ -60,14 +60,7 @@ export enum NotebookRunState {
|
|||
Idle = 2
|
||||
}
|
||||
|
||||
export const notebookDocumentMetadataDefaults: Required<NotebookDocumentMetadata> = {
|
||||
custom: {},
|
||||
};
|
||||
|
||||
export interface NotebookDocumentMetadata {
|
||||
custom?: { [key: string]: unknown; };
|
||||
[key: string]: unknown;
|
||||
}
|
||||
export type NotebookDocumentMetadata = Record<string, unknown>;
|
||||
|
||||
// Aligns with the vscode.d.ts version
|
||||
export enum NotebookCellExecutionState {
|
||||
|
|
|
@ -20,7 +20,7 @@ import { NotebookEventDispatcher } from 'vs/workbench/contrib/notebook/browser/v
|
|||
import { NotebookViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/notebookViewModel';
|
||||
import { ViewContext } from 'vs/workbench/contrib/notebook/browser/viewModel/viewContext';
|
||||
import { NotebookTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookTextModel';
|
||||
import { CellKind, diff, notebookDocumentMetadataDefaults } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
import { CellKind, diff } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
import { NotebookOptions } from 'vs/workbench/contrib/notebook/common/notebookOptions';
|
||||
import { ICellRange } from 'vs/workbench/contrib/notebook/common/notebookRange';
|
||||
import { NotebookEditorTestModel, setupInstantiationService, withTestNotebook } from 'vs/workbench/contrib/notebook/test/testNotebookEditor';
|
||||
|
@ -37,7 +37,7 @@ suite('NotebookViewModel', () => {
|
|||
instantiationService.stub(IThemeService, new TestThemeService());
|
||||
|
||||
test('ctor', function () {
|
||||
const notebook = new NotebookTextModel('notebook', URI.parse('test'), [], notebookDocumentMetadataDefaults, { transientCellMetadata: {}, transientDocumentMetadata: {}, transientOutputs: false }, undoRedoService, modelService, modeService);
|
||||
const notebook = new NotebookTextModel('notebook', URI.parse('test'), [], {}, { transientCellMetadata: {}, transientDocumentMetadata: {}, transientOutputs: false }, undoRedoService, modelService, modeService);
|
||||
const model = new NotebookEditorTestModel(notebook);
|
||||
const viewContext = new ViewContext(new NotebookOptions(instantiationService.get(IConfigurationService)), new NotebookEventDispatcher());
|
||||
const viewModel = new NotebookViewModel('notebook', model.notebook, viewContext, null, instantiationService, bulkEditService, undoRedoService, textModelService);
|
||||
|
|
|
@ -21,7 +21,7 @@ import { NotebookEventDispatcher } from 'vs/workbench/contrib/notebook/browser/v
|
|||
import { CellViewModel, NotebookViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/notebookViewModel';
|
||||
import { NotebookCellTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookCellTextModel';
|
||||
import { NotebookTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookTextModel';
|
||||
import { CellKind, CellUri, INotebookDiffEditorModel, INotebookEditorModel, IOutputDto, IResolvedNotebookEditorModel, NotebookCellMetadata, notebookDocumentMetadataDefaults } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
import { CellKind, CellUri, INotebookDiffEditorModel, INotebookEditorModel, IOutputDto, IResolvedNotebookEditorModel, NotebookCellMetadata, } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
import { ICellRange } from 'vs/workbench/contrib/notebook/common/notebookRange';
|
||||
import { TextModelResolverService } from 'vs/workbench/services/textmodelResolver/common/textModelResolverService';
|
||||
import { IModelService } from 'vs/editor/common/services/modelService';
|
||||
|
@ -176,7 +176,7 @@ function _createTestNotebookEditor(instantiationService: TestInstantiationServic
|
|||
outputs: cell[3] ?? [],
|
||||
metadata: cell[4]
|
||||
};
|
||||
}), notebookDocumentMetadataDefaults, { transientCellMetadata: {}, transientDocumentMetadata: {}, transientOutputs: false });
|
||||
}), {}, { transientCellMetadata: {}, transientDocumentMetadata: {}, transientOutputs: false });
|
||||
|
||||
const model = new NotebookEditorTestModel(notebook);
|
||||
const viewContext = new ViewContext(new NotebookOptions(instantiationService.get(IConfigurationService)), new NotebookEventDispatcher());
|
||||
|
|
Loading…
Reference in a new issue