Merge branch 'notebook/dev' into main

This commit is contained in:
rebornix 2021-05-25 14:24:16 -07:00
commit 6bcd590a70
28 changed files with 233 additions and 125 deletions

View file

@ -40,7 +40,7 @@
}
},
"contributes": {
"notebookOutputRenderer": [
"notebookRenderer": [
{
"id": "markdownItRenderer",
"displayName": "Markdown it renderer",

View file

@ -21,7 +21,7 @@
}
},
"contributes": {
"notebookOutputRenderer": [
"notebookRenderer": [
{
"id": "markdownItRenderer-katex",
"displayName": "Markdown it katex renderer",

View file

@ -60,13 +60,13 @@ class Kernel {
task.executionOrder = 1;
if (cell.notebook.uri.path.endsWith('customRenderer.vsctestnb')) {
await task.replaceOutput([new vscode.NotebookCellOutput([
new vscode.NotebookCellOutputItem('text/custom', ['test'], undefined)
vscode.NotebookCellOutputItem.text('test', 'text/custom', undefined)
])]);
return;
}
await task.replaceOutput([new vscode.NotebookCellOutput([
new vscode.NotebookCellOutputItem('text/plain', ['my output'], undefined)
vscode.NotebookCellOutputItem.text('my output', 'text/plain', undefined)
])]);
task.end({ success: true });
}
@ -129,7 +129,7 @@ suite('Notebook API tests', function () {
kind: vscode.NotebookCellKind.Code,
outputs: [
new vscode.NotebookCellOutput([
new vscode.NotebookCellOutputItem('text/plain', 'Hello World', { testOutputItemMetadata: true })
vscode.NotebookCellOutputItem.text('Hello World', 'text/plain', { testOutputItemMetadata: true })
],
{ testOutputMetadata: true })
],
@ -182,7 +182,7 @@ suite('Notebook API tests', function () {
const task = this.controller.createNotebookCellExecutionTask(cell);
task.start();
await task.replaceOutput([new vscode.NotebookCellOutput([
new vscode.NotebookCellOutputItem('text/plain', ['my second output'], undefined)
vscode.NotebookCellOutputItem.text('my second output', 'text/plain', undefined)
])]);
task.end({ success: true });
}
@ -779,7 +779,7 @@ suite('Notebook API tests', function () {
task.start();
task.token.onCancellationRequested(async () => {
await task.replaceOutput([new vscode.NotebookCellOutput([
new vscode.NotebookCellOutputItem('text/plain', ['Canceled'], undefined)
vscode.NotebookCellOutputItem.text('Canceled', 'text/plain', undefined)
])]);
task.end({});
});
@ -801,9 +801,7 @@ suite('Notebook API tests', function () {
assert.strictEqual(cell.outputs.length, 1, 'should execute'); // runnable, it worked
assert.strictEqual(cell.outputs[0].outputs.length, 1);
assert.strictEqual(cell.outputs[0].outputs[0].mime, 'text/plain');
assert.deepStrictEqual(cell.outputs[0].outputs[0].value, [
'Canceled'
]);
assert.deepStrictEqual(cell.outputs[0].outputs[0].value, 'Canceled');
});
cancelableKernel.controller.dispose();
@ -826,7 +824,7 @@ suite('Notebook API tests', function () {
async interrupt() {
await this._task!.replaceOutput([new vscode.NotebookCellOutput([
new vscode.NotebookCellOutputItem('text/plain', ['Interrupted'], undefined)
vscode.NotebookCellOutputItem.text('Interrupted', 'text/plain', undefined)
])]);
this._task!.end({});
}
@ -1188,7 +1186,7 @@ suite('Notebook API tests', function () {
const task = this.controller.createNotebookCellExecutionTask(cell);
task.start();
await task.replaceOutput([new vscode.NotebookCellOutput([
new vscode.NotebookCellOutputItem('text/plain', ['Some output'], undefined)
vscode.NotebookCellOutputItem.text('Some output', 'text/plain', undefined)
])]);
assert.strictEqual(cell.notebook.cellAt(0).outputs.length, 1);
assert.deepStrictEqual(cell.notebook.cellAt(0).outputs[0].outputs[0].value, ['Some output']);

View file

@ -46,7 +46,7 @@
]
}
],
"notebookOutputRenderer": [
"notebookRenderer": [
{
"id": "notebookCoreTestRenderer",
"displayName": "Notebook Core Test Renderer",

View file

@ -69,7 +69,7 @@ export function activate(context: vscode.ExtensionContext): any {
const task = controller.createNotebookCellExecutionTask(cell);
task.start();
task.replaceOutput([new vscode.NotebookCellOutput([
new vscode.NotebookCellOutputItem('text/html', ['test output'], undefined)
vscode.NotebookCellOutputItem.text('test output', 'text/html', undefined)
])]);
task.end({ success: true });
}

View file

@ -4,7 +4,7 @@
<head>
<meta charset="utf-8" />
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; img-src 'self' https: data: blob: vscode-remote-resource:; media-src 'none'; frame-src 'self' vscode-webview:; object-src 'self'; script-src 'self' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; connect-src 'self' https: ws:; font-src 'self' https: vscode-remote-resource:;">
<meta http-equiv="Content-Security-Policy" content="require-trusted-types-for 'script'; trusted-types default TrustedFunctionWorkaround ExtensionScripts amdLoader cellRendererEditorText defaultWorkerFactory diffEditorWidget editorGhostText domLineBreaksComputer editorViewLayer diffReview extensionHostWorker insane notebookOutputRenderer safeInnerHtml standaloneColorizer tokenizeToString webNestedWorkerExtensionHost webWorkerExtensionHost;">
<meta http-equiv="Content-Security-Policy" content="require-trusted-types-for 'script'; trusted-types default TrustedFunctionWorkaround ExtensionScripts amdLoader cellRendererEditorText defaultWorkerFactory diffEditorWidget editorGhostText domLineBreaksComputer editorViewLayer diffReview extensionHostWorker insane notebookRenderer safeInnerHtml standaloneColorizer tokenizeToString webNestedWorkerExtensionHost webWorkerExtensionHost;">
</head>
<body aria-label="">
</body>

View file

@ -4,7 +4,7 @@
<head>
<meta charset="utf-8" />
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; img-src 'self' https: data: blob: vscode-remote-resource:; media-src 'none'; frame-src 'self' vscode-webview:; object-src 'self'; script-src 'self' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; connect-src 'self' https: ws:; font-src 'self' https: vscode-remote-resource:;">
<meta http-equiv="Content-Security-Policy" content="require-trusted-types-for 'script'; trusted-types default TrustedFunctionWorkaround ExtensionScripts amdLoader cellRendererEditorText defaultWorkerFactory diffEditorWidget editorGhostText domLineBreaksComputer editorViewLayer diffReview extensionHostWorker insane notebookOutputRenderer safeInnerHtml standaloneColorizer tokenizeToString webNestedWorkerExtensionHost webWorkerExtensionHost;">
<meta http-equiv="Content-Security-Policy" content="require-trusted-types-for 'script'; trusted-types default TrustedFunctionWorkaround ExtensionScripts amdLoader cellRendererEditorText defaultWorkerFactory diffEditorWidget editorGhostText domLineBreaksComputer editorViewLayer diffReview extensionHostWorker insane notebookRenderer safeInnerHtml standaloneColorizer tokenizeToString webNestedWorkerExtensionHost webWorkerExtensionHost;">
</head>
<body aria-label="">
</body>

View file

@ -1247,11 +1247,12 @@ declare module 'vscode' {
*
* *Note* that an UTF-8 encoder is used to create bytes for the string.
*
* @param value A string/
* @param value A string.
* @param mime Optional MIME type, defaults to `text/plain`.
* @param metadata Optional metadata.
* @returns A new output item object.
*/
static text(value: string, mime?: string): NotebookCellOutputItem;
static text(value: string, mime?: string, metadata?: { [key: string]: any }): NotebookCellOutputItem;
/**
* Factory function to create a `NotebookCellOutputItem` from
@ -1263,46 +1264,40 @@ declare module 'vscode' {
*
* @param value A JSON-stringifyable value.
* @param mime Optional MIME type, defaults to `application/json`
* @param metadata Optional metadata.
* @returns A new output item object.
*/
static json(value: any, mime?: string): NotebookCellOutputItem;
/**
* Factory function to create a `NotebookCellOutputItem` from bytes.
*
* @param value An array of unsigned 8-bit integers.
* @param mime Optional MIME type, defaults to `application/octet-stream`.
* @returns A new output item object.
*/
//todo@API better names: bytes, raw, buffer?
static bytes(value: Uint8Array, mime?: string): NotebookCellOutputItem;
static json(value: any, mime?: string, metadata?: { [key: string]: any }): NotebookCellOutputItem;
/**
* Factory function to create a `NotebookCellOutputItem` that uses
* uses the `application/vnd.code.notebook.stdout` mime type.
*
* @param value A string.
* @param metadata Optional metadata.
* @returns A new output item object.
*/
static stdout(value: string): NotebookCellOutputItem;
static stdout(value: string, metadata?: { [key: string]: any }): NotebookCellOutputItem;
/**
* Factory function to create a `NotebookCellOutputItem` that uses
* uses the `application/vnd.code.notebook.stderr` mime type.
*
* @param value A string.
* @param metadata Optional metadata.
* @returns A new output item object.
*/
static stderr(value: string): NotebookCellOutputItem;
static stderr(value: string, metadata?: { [key: string]: any }): NotebookCellOutputItem;
/**
* Factory function to create a `NotebookCellOutputItem` that uses
* uses the `application/vnd.code.notebook.error` mime type.
*
* @param value An error object.
* @param metadata Optional metadata.
* @returns A new output item object.
*/
static error(value: Error): NotebookCellOutputItem;
static error(value: Error, metadata?: { [key: string]: any }): NotebookCellOutputItem;
/**
* The mime type which determines how the {@link NotebookCellOutputItem.value `value`}-property
@ -1314,21 +1309,26 @@ declare module 'vscode' {
mime: string;
/**
* The value of this output item. Must always be an array of unsigned 8-bit integers.
* The data of this output item. Must always be an array of unsigned 8-bit integers.
*/
//todo@API only Unit8Array
value: Uint8Array | unknown;
data: Uint8Array;
/**
* @deprecated
*/
value: unknown;
//todo@API
metadata?: { [key: string]: any };
/**
* Create a new notbook cell output item.
*
* @param data The value of the output item.
* @param mime The mime type of the output item.
* @param value The value of the output item.
* @param metadata Optional metadata for this output item.
*/
constructor(mime: string, value: Uint8Array | unknown, metadata?: { [key: string]: any });
constructor(data: Uint8Array, mime: string, metadata?: { [key: string]: any });
}
// @jrieken transient
@ -1563,6 +1563,9 @@ declare module 'vscode' {
/**
* The identifier of this notebook controller.
*
* _Note_ that controllers are remembered by their identifier and that extensions should use
* stable identifiers across sessions.
*/
readonly id: string;
@ -1654,6 +1657,7 @@ declare module 'vscode' {
* @param cell The notebook cell for which to create the execution.
* @returns A notebook cell execution.
*/
// todo@API rename to NotebookCellExecution
createNotebookCellExecutionTask(cell: NotebookCell): NotebookCellExecutionTask;
// todo@API find a better name than "preloads"

View file

@ -4,7 +4,6 @@
*--------------------------------------------------------------------------------------------*/
import { coalesce, isNonEmptyArray } from 'vs/base/common/arrays';
import { VSBuffer } from 'vs/base/common/buffer';
import * as htmlContent from 'vs/base/common/htmlContent';
import { DisposableStore } from 'vs/base/common/lifecycle';
import * as marked from 'vs/base/common/marked/marked';
@ -1536,9 +1535,9 @@ export namespace NotebookCellOutputItem {
export function from(item: types.NotebookCellOutputItem): notebooks.IOutputItemDto {
let value: unknown;
let valueBytes: number[] | undefined;
if (item.value instanceof Uint8Array) {
if (item.data instanceof Uint8Array) {
//todo@jrieken this HACKY and SLOW... hoist VSBuffer instead
valueBytes = Array.from(item.value);
valueBytes = Array.from(item.data);
} else {
value = item.value;
}
@ -1551,15 +1550,13 @@ export namespace NotebookCellOutputItem {
}
export function to(item: notebooks.IOutputItemDto): types.NotebookCellOutputItem {
let value: Uint8Array | unknown;
if (item.value instanceof VSBuffer) {
value = item.value.buffer;
let value: Uint8Array | any;
if (Array.isArray(item.valueBytes)) {
value = new Uint8Array(item.valueBytes);
} else {
value = item.value;
}
return new types.NotebookCellOutputItem(item.mime, value, item.metadata);
return new types.NotebookCellOutputItem(value, item.mime, item.metadata);
}
}

View file

@ -3112,44 +3112,50 @@ export class NotebookCellOutputItem {
return typeof (<vscode.NotebookCellOutputItem>obj).mime === 'string';
}
static error(err: Error | { name: string, message?: string, stack?: string }): NotebookCellOutputItem {
static error(err: Error | { name: string, message?: string, stack?: string }, metadata?: { [key: string]: any }): NotebookCellOutputItem {
const obj = {
name: err.name,
message: err.message,
stack: err.stack
};
return NotebookCellOutputItem.json(obj, 'application/vnd.code.notebook.error');
return NotebookCellOutputItem.json(obj, 'application/vnd.code.notebook.error', metadata);
}
static stdout(value: string): NotebookCellOutputItem {
return NotebookCellOutputItem.text(value, 'application/vnd.code.notebook.stdout');
static stdout(value: string, metadata?: { [key: string]: any }): NotebookCellOutputItem {
return NotebookCellOutputItem.text(value, 'application/vnd.code.notebook.stdout', metadata);
}
static stderr(value: string): NotebookCellOutputItem {
return NotebookCellOutputItem.text(value, 'application/vnd.code.notebook.stderr');
static stderr(value: string, metadata?: { [key: string]: any }): NotebookCellOutputItem {
return NotebookCellOutputItem.text(value, 'application/vnd.code.notebook.stderr', metadata);
}
static bytes(value: Uint8Array, mime: string = 'application/octet-stream'): NotebookCellOutputItem {
return new NotebookCellOutputItem(mime, value);
static bytes(value: Uint8Array, mime: string = 'application/octet-stream', metadata?: { [key: string]: any }): NotebookCellOutputItem {
return new NotebookCellOutputItem(value, mime, metadata);
}
static #encoder = new TextEncoder();
static text(value: string, mime: string = 'text/plain'): NotebookCellOutputItem {
static text(value: string, mime: string = 'text/plain', metadata?: { [key: string]: any }): NotebookCellOutputItem {
const bytes = NotebookCellOutputItem.#encoder.encode(String(value));
return new NotebookCellOutputItem(mime, bytes);
return new NotebookCellOutputItem(bytes, mime, metadata);
}
static json(value: any, mime: string = 'application/json'): NotebookCellOutputItem {
static json(value: any, mime: string = 'application/json', metadata?: { [key: string]: any }): NotebookCellOutputItem {
const rawStr = JSON.stringify(value, undefined, '\t');
return NotebookCellOutputItem.text(rawStr, mime);
return NotebookCellOutputItem.text(rawStr, mime, metadata);
}
/** @deprecated */
public value: Uint8Array | unknown; // JSON'able
constructor(
public data: Uint8Array,
public mime: string,
public value: Uint8Array | unknown, // JSON'able
public metadata?: Record<string, any>
public metadata?: { [key: string]: any }
) {
if (!(data instanceof Uint8Array)) {
this.value = data;
}
if (isFalsyOrWhitespace(this.mime)) {
throw new Error('INVALID mime type, must not be empty or falsy');
}

View file

@ -192,6 +192,6 @@ export const notebooksExtensionPoint = ExtensionsRegistry.registerExtensionPoint
export const notebookRendererExtensionPoint = ExtensionsRegistry.registerExtensionPoint<INotebookRendererContribution[]>(
{
extensionPoint: 'notebookOutputRenderer',
extensionPoint: 'notebookRenderer',
jsonSchema: notebookRendererContribution
});

View file

@ -425,7 +425,7 @@
overflow: hidden;
}
.monaco-workbench .notebookOverlay.cell-statusbar-hidden .cell-statusbar-container {
.monaco-workbench .notebookOverlay .cell-statusbar-hidden .cell-statusbar-container {
display: none;
}

View file

@ -30,7 +30,7 @@ import { NotebookEditor } from 'vs/workbench/contrib/notebook/browser/notebookEd
import { NotebookEditorInput } from 'vs/workbench/contrib/notebook/common/notebookEditorInput';
import { INotebookService } from 'vs/workbench/contrib/notebook/common/notebookService';
import { NotebookService } from 'vs/workbench/contrib/notebook/browser/notebookServiceImpl';
import { CellKind, CellToolbarLocKey, CellToolbarVisibility, CellUri, DisplayOrderKey, UndoRedoPerCell, ExperimentalUseMarkdownRenderer, getCellUndoRedoComparisonKey, IResolvedNotebookEditorModel, NotebookDocumentBackupData, NotebookTextDiffEditorPreview, NotebookWorkingCopyTypeIdentifier, ShowCellStatusBarKey, CompactView, FocusIndicator, InsertToolbarPosition, GlobalToolbar, ConsolidatedOutputButton, ShowFoldingControls, DragAndDropEnabled } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { CellKind, CellToolbarLocKey, CellToolbarVisibility, CellUri, DisplayOrderKey, UndoRedoPerCell, ExperimentalUseMarkdownRenderer, getCellUndoRedoComparisonKey, IResolvedNotebookEditorModel, NotebookDocumentBackupData, NotebookTextDiffEditorPreview, NotebookWorkingCopyTypeIdentifier, ShowCellStatusBarKey, CompactView, FocusIndicator, InsertToolbarPosition, GlobalToolbar, ConsolidatedOutputButton, ShowFoldingControls, DragAndDropEnabled, ShowCellStatusBarAfterExecuteKey } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { IUndoRedoService } from 'vs/platform/undoRedo/common/undoRedo';
import { INotebookEditorModelResolverService } from 'vs/workbench/contrib/notebook/common/notebookEditorModelResolverService';
@ -582,6 +582,12 @@ configurationRegistry.registerConfiguration({
default: true,
tags: ['notebookLayout']
},
[ShowCellStatusBarAfterExecuteKey]: {
description: nls.localize('notebook.showCellStatusbarAfterExecute.description', "Whether the cell status bar should be shown after the cell has been executed."),
type: 'boolean',
default: false,
tags: ['notebookLayout']
},
[NotebookTextDiffEditorPreview]: {
description: nls.localize('notebook.diff.enablePreview.description', "Whether to use the enhanced text diff editor for notebook."),
type: 'boolean',

View file

@ -235,6 +235,7 @@ export interface MarkdownCellLayoutInfo {
readonly fontInfo: FontInfo | null;
readonly editorWidth: number;
readonly editorHeight: number;
readonly previewHeight: number;
readonly bottomToolbarOffset: number;
readonly totalHeight: number;
}
@ -242,6 +243,8 @@ export interface MarkdownCellLayoutInfo {
export interface MarkdownCellLayoutChangeEvent {
font?: FontInfo;
outerWidth?: number;
editorHeight?: number;
previewHeight?: number;
totalHeight?: number;
}

View file

@ -511,9 +511,6 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditor
const cellToolbarLocation = this._notebookOptions.computeCellToolbarLocation(this.viewModel?.viewType);
this._overlayContainer.classList.add(`cell-title-toolbar-${cellToolbarLocation}`);
const showCellStatusBar = this._notebookOptions.getLayoutConfiguration().showCellStatusBar;
this._overlayContainer.classList.toggle('cell-statusbar-hidden', !showCellStatusBar);
const cellToolbarInteraction = this._notebookOptions.getLayoutConfiguration().cellToolbarInteraction;
let cellToolbarInteractionState = 'hover';
this._overlayContainer.classList.remove('cell-toolbar-hover');
@ -555,6 +552,7 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditor
cellRunGutter,
cellBottomMargin,
codeCellLeftMargin,
markdownCellGutter,
markdownCellLeftMargin,
markdownCellBottomMargin,
markdownCellTopMargin,
@ -565,7 +563,8 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditor
focusIndicator,
insertToolbarPosition,
insertToolbarAlignment,
fontSize
fontSize,
focusIndicatorLeftMargin
} = this._notebookOptions.getLayoutConfiguration();
const styleSheets: string[] = [];
@ -643,12 +642,6 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditor
height: 100%;
z-index: 10;
}
.monaco-workbench .notebookOverlay .monaco-list .monaco-list-row .cell-focus-indicator-left:before {
border-left: 1px solid transparent;
border-right: 1px solid transparent;
border-radius: 2px;
}
`);
// left and right border margins
@ -659,6 +652,15 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditor
.monaco-workbench .notebookOverlay .monaco-list.selection-multiple .monaco-list-row.code-cell-row.selected .cell-focus-indicator-right:before {
top: 0px; height: 100%;
}`);
styleSheets.push(`
.monaco-workbench .notebookOverlay .monaco-list .monaco-list-row.focused .cell-focus-indicator-left:before,
.monaco-workbench .notebookOverlay .monaco-list .monaco-list-row.selected .cell-focus-indicator-left:before {
border-left: 2px solid transparent;
border-right: 1px solid transparent;
border-radius: 2px;
margin-left: ${focusIndicatorLeftMargin}px;
}`);
}
// between cell insert toolbar
@ -727,7 +729,7 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditor
styleSheets.push(`.monaco-workbench .notebookOverlay > .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .monaco-list-row .execution-count-label { left: ${codeCellLeftMargin}px; width: ${cellRunGutter}px; }`);
styleSheets.push(`.notebookOverlay .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .monaco-list-row div.cell.markdown { padding-left: ${cellRunGutter}px; }`);
styleSheets.push(`.monaco-workbench .notebookOverlay > .cell-list-container .notebook-folding-indicator { left: ${(markdownCellLeftMargin - 20) / 2}px; }`);
styleSheets.push(`.monaco-workbench .notebookOverlay > .cell-list-container .notebook-folding-indicator { left: ${(markdownCellGutter - 20) / 2 + markdownCellLeftMargin}px; }`);
styleSheets.push(`.notebookOverlay .monaco-list .monaco-list-row :not(.webview-backed-markdown-cell) .cell-focus-indicator-top { height: ${cellTopMargin}px; }`);
styleSheets.push(`.notebookOverlay .monaco-list .monaco-list-row .cell-focus-indicator-side { bottom: ${bottomCellToolbarGap}px; }`);
styleSheets.push(`.notebookOverlay .monaco-list .monaco-list-row.code-cell-row .cell-focus-indicator-left,
@ -2484,10 +2486,8 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditor
const cell = this.getCellById(cellId);
const layoutConfiguration = this._notebookOptions.getLayoutConfiguration();
if (cell && cell instanceof MarkdownCellViewModel) {
if (height + layoutConfiguration.bottomToolbarGap !== cell.layoutInfo.totalHeight) {
this._debug('updateMarkdownCellHeight', cell.handle, height + layoutConfiguration.bottomToolbarGap, isInit);
cell.renderedMarkdownHeight = height;
}
this._debug('updateMarkdownCellHeight', cell.handle, height + layoutConfiguration.bottomToolbarGap, isInit);
cell.renderedMarkdownHeight = height;
}
}

View file

@ -349,13 +349,13 @@ export class NotebookService extends Disposable implements INotebookService {
for (const extension of renderers) {
for (const notebookContribution of extension.value) {
if (!notebookContribution.entrypoint) { // avoid crashing
console.error(`Cannot register renderer for ${extension.description.identifier.value} since it did not have an entrypoint. This is now required: https://github.com/microsoft/vscode/issues/102644`);
extension.collector.error(`Notebook renderer does not specify entry point`);
continue;
}
const id = notebookContribution.id ?? notebookContribution.viewType;
if (!id) {
console.error(`Notebook renderer from ${extension.description.identifier.value} is missing an 'id'`);
extension.collector.error(`Notebook renderer does not specify id-property`);
continue;
}

View file

@ -521,6 +521,8 @@ export class MarkdownCellRenderer extends AbstractCellRenderer implements IListR
templateData.focusIndicatorBottom.style.top = `${indicatorPostion.bottomIndicatorTop}px`;
templateData.focusIndicatorLeft.style.height = `${indicatorPostion.verticalIndicatorHeight}px`;
templateData.focusIndicatorRight.style.height = `${indicatorPostion.verticalIndicatorHeight}px`;
templateData.container.classList.toggle('cell-statusbar-hidden', element.getEditorStatusbarHeight() === 0);
}
private updateForHover(element: MarkdownCellViewModel, templateData: MarkdownCellRenderTemplate): void {
@ -852,7 +854,7 @@ export class CodeCellRenderer extends AbstractCellRenderer implements IListRende
}
}
private updateForInternalMetadata(element: CodeCellViewModel, templateData: CodeCellRenderTemplate, editorOptions: CellEditorOptions): void {
private updateForInternalMetadata(element: CodeCellViewModel, templateData: CodeCellRenderTemplate): void {
if (!this.notebookEditor.hasModel()) {
return;
}
@ -894,6 +896,8 @@ export class CodeCellRenderer extends AbstractCellRenderer implements IListRende
templateData.outputContainer.style.top = `${element.layoutInfo.outputContainerOffset}px`;
templateData.outputShowMoreContainer.style.top = `${element.layoutInfo.outputShowMoreContainerOffset}px`;
templateData.dragHandle.style.height = `${element.layoutInfo.totalHeight - layoutInfo.bottomToolbarGap}px`;
templateData.container.classList.toggle('cell-statusbar-hidden', element.getEditorStatusbarHeight() === 0);
}
renderElement(element: CodeCellViewModel, index: number, templateData: CodeCellRenderTemplate, height: number | undefined): void {
@ -959,13 +963,14 @@ export class CodeCellRenderer extends AbstractCellRenderer implements IListRende
this.updateForLayout(element, templateData);
}));
this.updateForInternalMetadata(element, templateData, cellEditorOptions);
this.updateForInternalMetadata(element, templateData);
this.updateForHover(element, templateData);
this.updateForFocus(element, templateData);
cellEditorOptions.setLineNumbers(element.lineNumbers);
elementDisposables.add(element.onDidChangeState((e) => {
if (e.internalMetadataChanged) {
this.updateForInternalMetadata(element, templateData, cellEditorOptions);
this.updateForInternalMetadata(element, templateData);
this.updateForLayout(element, templateData);
}
if (e.outputIsHoveredChanged) {

View file

@ -250,6 +250,7 @@ export class StatefulMarkdownCell extends Disposable {
private updateFoldingIconShowClass() {
const showFoldingIcon = this.notebookEditor.notebookOptions.getLayoutConfiguration().showFoldingControls;
this.templateData.foldingIndicator.classList.remove('mouseover', 'always');
this.templateData.foldingIndicator.classList.add(showFoldingIcon);
}

View file

@ -468,8 +468,10 @@ async function webviewPreloads(style: PreloadStyles, options: PreloadOptions, re
text(): string;
json(): any;
bytes(): Uint8Array
data(): Uint8Array;
blob(): Blob;
/** @deprecated */
bytes(): Uint8Array;
}
interface IDestroyCellInfo {
@ -492,7 +494,7 @@ async function webviewPreloads(style: PreloadStyles, options: PreloadOptions, re
postKernelMessage: (data: unknown) => postNotebookMessage('customKernelMessage', { message: data }),
};
const ttPolicy = window.trustedTypes?.createPolicy('notebookOutputRenderer', {
const ttPolicy = window.trustedTypes?.createPolicy('notebookRenderer', {
createHTML: value => value,
createScript: value => value,
});
@ -643,9 +645,10 @@ async function webviewPreloads(style: PreloadStyles, options: PreloadOptions, re
mime: content.mimeType,
value: content.value,
metadata: content.metadata,
bytes() {
data() {
return content.valueBytes;
},
bytes() { return this.data(); },
text() {
return new TextDecoder().decode(content.valueBytes)
|| String(content.value); //todo@jrieken remove this once `value` is gone!
@ -1038,8 +1041,9 @@ async function webviewPreloads(style: PreloadStyles, options: PreloadOptions, re
outputId: undefined,
text() { return content; },
json() { return undefined; },
bytes() { return new Uint8Array(); },
blob() { return new Blob(); },
bytes() { return this.data(); },
data() { return new TextEncoder().encode(content); },
blob() { return new Blob([this.data()], { type: this.mime }); },
});
}
}();

View file

@ -144,10 +144,8 @@ export abstract class BaseCellViewModel extends Disposable {
this._register(model.onDidChangeInternalMetadata(e => {
this._onDidChangeState.fire({ internalMetadataChanged: true, runStateChanged: e.runStateChanged });
}));
this._register(this._viewContext.notebookOptions.onDidChangeOptions(e => {
if (e.cellStatusBarVisibility || e.insertToolbarPosition) {
if (e.runStateChanged || e.lastRunSuccessChanged) {
// Statusbar visibility may change
this.layoutChange({});
}
}));
@ -160,7 +158,17 @@ export abstract class BaseCellViewModel extends Disposable {
}
getEditorStatusbarHeight() {
return this._viewContext.notebookOptions.computeStatusBarHeight();
return this.statusBarIsVisible() ? this._viewContext.notebookOptions.computeStatusBarHeight() : 0;
}
private statusBarIsVisible(): boolean {
if (this._viewContext.notebookOptions.getLayoutConfiguration().showCellStatusBar) {
return true;
} else if (this._viewContext.notebookOptions.getLayoutConfiguration().showCellStatusBarAfterExecute) {
return typeof this.internalMetadata.lastRunSuccess === 'boolean' || this.internalMetadata.runState !== undefined;
} else {
return false;
}
}
abstract hasDynamicHeight(): boolean;

View file

@ -126,6 +126,12 @@ export class CodeCellViewModel extends BaseCellViewModel implements ICellViewMod
}
}));
this._register(this.viewContext.notebookOptions.onDidChangeOptions(e => {
if (e.cellStatusBarVisibility || e.cellStatusBarAfterExecuteVisibility || e.insertToolbarPosition) {
this.layoutChange({});
}
}));
this._outputCollection = new Array(this.model.outputs.length);
this._layoutInfo = {
@ -152,6 +158,7 @@ export class CodeCellViewModel extends BaseCellViewModel implements ICellViewMod
const outputShowMoreContainerHeight = state.outputShowMoreContainerHeight ? state.outputShowMoreContainerHeight : this._layoutInfo.outputShowMoreContainerHeight;
let outputTotalHeight = Math.max(this._outputMinHeight, this.metadata.outputCollapsed ? notebookLayoutConfiguration.collapsedIndicatorHeight : this._outputsTop!.getTotalValue());
const originalLayout = this.layoutInfo;
if (!this.metadata.inputCollapsed) {
let newState: CodeCellLayoutState;
let editorHeight: number;
@ -235,10 +242,7 @@ export class CodeCellViewModel extends BaseCellViewModel implements ICellViewMod
};
}
if (state.editorHeight || state.outputHeight) {
state.totalHeight = true;
}
state.totalHeight = this.layoutInfo.totalHeight !== originalLayout.totalHeight;
state.source = source;
this._fireOnDidChangeLayout(state);

View file

@ -27,33 +27,25 @@ export class MarkdownCellViewModel extends BaseCellViewModel implements ICellVie
return this._layoutInfo;
}
private _previewHeight = 0;
set renderedMarkdownHeight(newHeight: number) {
if (this.getEditState() === CellEditState.Preview) {
const newTotalHeight = newHeight + this.viewContext.notebookOptions.getLayoutConfiguration().bottomToolbarGap; // BOTTOM_CELL_TOOLBAR_GAP;
this.totalHeight = newTotalHeight;
this._previewHeight = newHeight;
this._updateTotalHeight(this._previewHeight + this.viewContext.notebookOptions.getLayoutConfiguration().bottomToolbarGap);
}
}
private set totalHeight(newHeight: number) {
if (newHeight !== this.layoutInfo.totalHeight) {
this.layoutChange({ totalHeight: newHeight });
}
}
private get totalHeight() {
throw new Error('MarkdownCellViewModel.totalHeight is write only');
}
private _editorHeight = 0;
set editorHeight(newHeight: number) {
this._editorHeight = newHeight;
const layoutConfiguration = this.viewContext.notebookOptions.getLayoutConfiguration();
this.totalHeight = this._editorHeight
this._updateTotalHeight(this._editorHeight
+ layoutConfiguration.markdownCellTopMargin // MARKDOWN_CELL_TOP_MARGIN
+ layoutConfiguration.markdownCellBottomMargin // MARKDOWN_CELL_BOTTOM_MARGIN
+ layoutConfiguration.bottomToolbarGap // BOTTOM_CELL_TOOLBAR_GAP
+ this.viewContext.notebookOptions.computeStatusBarHeight();
+ this.viewContext.notebookOptions.computeStatusBarHeight());
}
get editorHeight() {
@ -116,6 +108,7 @@ export class MarkdownCellViewModel extends BaseCellViewModel implements ICellVie
this._layoutInfo = {
editorHeight: 0,
previewHeight: 0,
fontInfo: initialNotebookLayoutInfo?.fontInfo || null,
editorWidth: initialNotebookLayoutInfo?.width
? this.viewContext.notebookOptions.computeMarkdownCellEditorWidth(initialNotebookLayoutInfo.width)
@ -133,6 +126,21 @@ export class MarkdownCellViewModel extends BaseCellViewModel implements ICellVie
this._onDidHideInput.fire();
}
}));
this._register(this.viewContext.notebookOptions.onDidChangeOptions(e => {
if (e.cellStatusBarVisibility || e.cellStatusBarAfterExecuteVisibility || e.insertToolbarPosition) {
const layoutConfiguration = this.viewContext.notebookOptions.getLayoutConfiguration();
if (this.getEditState() === CellEditState.Editing) {
this._updateTotalHeight(this._editorHeight
+ layoutConfiguration.markdownCellTopMargin
+ layoutConfiguration.markdownCellBottomMargin
+ layoutConfiguration.bottomToolbarGap
+ this.viewContext.notebookOptions.computeStatusBarHeight());
} else {
this._updateTotalHeight(this._previewHeight + this.viewContext.notebookOptions.getLayoutConfiguration().bottomToolbarGap);
}
}
}));
}
/**
@ -151,6 +159,12 @@ export class MarkdownCellViewModel extends BaseCellViewModel implements ICellVie
this._onDidChangeState.fire({ foldingStateChanged: true });
}
private _updateTotalHeight(newHeight: number) {
if (newHeight !== this.layoutInfo.totalHeight) {
this.layoutChange({ totalHeight: newHeight });
}
}
layoutChange(state: MarkdownCellLayoutChangeEvent) {
// recompute
if (!this.metadata.inputCollapsed) {
@ -158,10 +172,12 @@ export class MarkdownCellViewModel extends BaseCellViewModel implements ICellVie
? this.viewContext.notebookOptions.computeMarkdownCellEditorWidth(state.outerWidth)
: this._layoutInfo.editorWidth;
const totalHeight = state.totalHeight === undefined ? this._layoutInfo.totalHeight : state.totalHeight;
const previewHeight = this._previewHeight;
this._layoutInfo = {
fontInfo: state.font || this._layoutInfo.fontInfo,
editorWidth,
previewHeight,
editorHeight: this._editorHeight,
bottomToolbarOffset: this.viewContext.notebookOptions.computeBottomToolbarOffset(totalHeight),
totalHeight
@ -178,6 +194,7 @@ export class MarkdownCellViewModel extends BaseCellViewModel implements ICellVie
fontInfo: state.font || this._layoutInfo.fontInfo,
editorWidth,
editorHeight: this._editorHeight,
previewHeight: this._previewHeight,
bottomToolbarOffset: this.viewContext.notebookOptions.computeBottomToolbarOffset(totalHeight),
totalHeight
};
@ -193,6 +210,7 @@ export class MarkdownCellViewModel extends BaseCellViewModel implements ICellVie
this._layoutInfo = {
fontInfo: this._layoutInfo.fontInfo,
editorWidth: this._layoutInfo.editorWidth,
previewHeight: this._layoutInfo.previewHeight,
bottomToolbarOffset: this._layoutInfo.bottomToolbarOffset,
totalHeight: totalHeight,
editorHeight: this._editorHeight

View file

@ -59,13 +59,14 @@ export class NotebookCellTextModel extends Disposable implements ICell {
set internalMetadata(newInternalMetadata: NotebookCellInternalMetadata) {
const runStateChanged = this._internalMetadata.runState !== newInternalMetadata.runState;
const lastRunSuccessChanged = this._internalMetadata.lastRunSuccess !== newInternalMetadata.lastRunSuccess;
newInternalMetadata = {
...newInternalMetadata,
...{ runStartTimeAdjustment: computeRunStartTimeAdjustment(this._internalMetadata, newInternalMetadata) }
};
this._internalMetadata = newInternalMetadata;
this._hash = null;
this._onDidChangeInternalMetadata.fire({ runStateChanged });
this._onDidChangeInternalMetadata.fire({ runStateChanged, lastRunSuccessChanged });
}
get language() {

View file

@ -189,6 +189,7 @@ export interface ICellOutput {
export interface CellInternalMetadataChangedEvent {
readonly runStateChanged?: boolean;
readonly lastRunSuccessChanged?: boolean;
}
export interface ICell {
@ -903,6 +904,7 @@ export const DisplayOrderKey = 'notebook.displayOrder';
export const CellToolbarLocKey = 'notebook.cellToolbarLocation';
export const CellToolbarVisibility = 'notebook.cellToolbarVisibility';
export const ShowCellStatusBarKey = 'notebook.showCellStatusBar';
export const ShowCellStatusBarAfterExecuteKey = 'notebook.showCellStatusBarAfterExecute';
export const NotebookTextDiffEditorPreview = 'notebook.diff.enablePreview';
export const ExperimentalUseMarkdownRenderer = 'notebook.experimental.useMarkdownRenderer';
export const ExperimentalInsertToolbarAlignment = 'notebook.experimental.insertToolbarAlignment';

View file

@ -6,7 +6,7 @@
import { Emitter } from 'vs/base/common/event';
import { IDisposable } from 'vs/base/common/lifecycle';
import { IConfigurationChangeEvent, IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { CellToolbarLocKey, CellToolbarVisibility, CompactView, ConsolidatedOutputButton, DragAndDropEnabled, FocusIndicator, GlobalToolbar, ExperimentalInsertToolbarAlignment, InsertToolbarPosition, ShowFoldingControls, ShowCellStatusBarKey } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { CellToolbarLocKey, CellToolbarVisibility, CompactView, ConsolidatedOutputButton, DragAndDropEnabled, ExperimentalInsertToolbarAlignment, FocusIndicator, GlobalToolbar, InsertToolbarPosition, ShowCellStatusBarAfterExecuteKey, ShowCellStatusBarKey, ShowFoldingControls } from 'vs/workbench/contrib/notebook/common/notebookCommon';
const SCROLLABLE_ELEMENT_PADDING_TOP = 18;
@ -32,6 +32,7 @@ export interface NotebookLayoutConfiguration {
cellOutputPadding: number;
codeCellLeftMargin: number;
markdownCellLeftMargin: number;
markdownCellGutter: number;
markdownCellTopMargin: number;
markdownCellBottomMargin: number;
markdownPreviewPadding: number;
@ -43,6 +44,7 @@ export interface NotebookLayoutConfiguration {
editorBottomPaddingWithoutStatusBar: number;
collapsedIndicatorHeight: number;
showCellStatusBar: boolean;
showCellStatusBarAfterExecute: boolean;
cellStatusBarHeight: number;
cellToolbarLocation: string | { [key: string]: string };
cellToolbarInteraction: string;
@ -55,10 +57,12 @@ export interface NotebookLayoutConfiguration {
showFoldingControls: 'always' | 'mouseover';
dragAndDropEnabled: boolean;
fontSize: number;
focusIndicatorLeftMargin: number;
}
interface NotebookOptionsChangeEvent {
cellStatusBarVisibility?: boolean;
cellStatusBarAfterExecuteVisibility?: boolean;
cellToolbarLocation?: boolean;
cellToolbarInteraction?: boolean;
editorTopPadding?: boolean;
@ -78,15 +82,19 @@ const defaultConfigConstants = {
cellRunGutter: 32,
markdownCellTopMargin: 8,
markdownCellBottomMargin: 8,
markdownCellLeftMargin: 32,
markdownCellLeftMargin: 0,
markdownCellGutter: 32,
focusIndicatorLeftMargin: 4
};
const compactConfigConstants = {
codeCellLeftMargin: 0,
codeCellLeftMargin: 8,
cellRunGutter: 32,
markdownCellTopMargin: 6,
markdownCellBottomMargin: 6,
markdownCellLeftMargin: 32,
markdownCellLeftMargin: 8,
markdownCellGutter: 32,
focusIndicatorLeftMargin: 4
};
export class NotebookOptions {
@ -97,6 +105,7 @@ export class NotebookOptions {
constructor(private readonly configurationService: IConfigurationService) {
const showCellStatusBar = this.configurationService.getValue<boolean>(ShowCellStatusBarKey);
const showCellStatusBarAfterExecute = this.configurationService.getValue<boolean>(ShowCellStatusBarAfterExecuteKey);
const globalToolbar = this.configurationService.getValue<boolean | undefined>(GlobalToolbar) ?? false;
const consolidatedOutputButton = this.configurationService.getValue<boolean | undefined>(ConsolidatedOutputButton) ?? true;
const dragAndDropEnabled = this.configurationService.getValue<boolean | undefined>(DragAndDropEnabled) ?? true;
@ -127,6 +136,7 @@ export class NotebookOptions {
editorBottomPaddingWithoutStatusBar: 12,
collapsedIndicatorHeight: 24,
showCellStatusBar,
showCellStatusBarAfterExecute,
globalToolbar,
consolidatedOutputButton,
dragAndDropEnabled,
@ -154,6 +164,7 @@ export class NotebookOptions {
private _updateConfiguration(e: IConfigurationChangeEvent) {
const cellStatusBarVisibility = e.affectsConfiguration(ShowCellStatusBarKey);
const cellStatusBarAfterExecuteVisibility = e.affectsConfiguration(ShowCellStatusBarAfterExecuteKey);
const cellToolbarLocation = e.affectsConfiguration(CellToolbarLocKey);
const cellToolbarInteraction = e.affectsConfiguration(CellToolbarVisibility);
const compactView = e.affectsConfiguration(CompactView);
@ -168,6 +179,7 @@ export class NotebookOptions {
if (
!cellStatusBarVisibility
&& !cellStatusBarAfterExecuteVisibility
&& !cellToolbarLocation
&& !cellToolbarInteraction
&& !compactView
@ -188,6 +200,10 @@ export class NotebookOptions {
configuration.showCellStatusBar = this.configurationService.getValue<boolean>(ShowCellStatusBarKey);
}
if (cellStatusBarAfterExecuteVisibility) {
configuration.showCellStatusBarAfterExecute = this.configurationService.getValue<boolean>(ShowCellStatusBarAfterExecuteKey);
}
if (cellToolbarLocation) {
configuration.cellToolbarLocation = this.configurationService.getValue<string | { [key: string]: string }>(CellToolbarLocKey);
}
@ -244,6 +260,7 @@ export class NotebookOptions {
// trigger event
this._onDidChangeOptions.fire({
cellStatusBarVisibility,
cellStatusBarAfterExecuteVisibility,
cellToolbarLocation,
cellToolbarInteraction,
compactView,
@ -329,11 +346,7 @@ export class NotebookOptions {
}
computeStatusBarHeight(): number {
if (this._layoutConfiguration.showCellStatusBar) {
return this._layoutConfiguration.cellStatusBarHeight;
} else {
return 0;
}
return this._layoutConfiguration.cellStatusBarHeight;
}
computeCellToolbarLocation(viewType?: string): 'right' | 'left' | 'hidden' {
@ -384,7 +397,7 @@ export class NotebookOptions {
outputNodePadding: this._layoutConfiguration.cellOutputPadding,
outputNodeLeftPadding: this._layoutConfiguration.cellOutputPadding,
previewNodePadding: this._layoutConfiguration.markdownPreviewPadding,
markdownLeftMargin: this._layoutConfiguration.markdownCellLeftMargin,
markdownLeftMargin: this._layoutConfiguration.markdownCellGutter + this._layoutConfiguration.markdownCellLeftMargin,
leftMargin: this._layoutConfiguration.codeCellLeftMargin,
rightMargin: this._layoutConfiguration.cellRightMargin,
runGutter: this._layoutConfiguration.cellRunGutter,

View file

@ -92,7 +92,25 @@ export class SettingsEditor2 extends EditorPane {
private static CONFIG_SCHEMA_UPDATE_DELAYER = 500;
private static readonly SUGGESTIONS: string[] = [
`@${MODIFIED_SETTING_TAG}`, '@tag:usesOnlineServices', '@tag:sync', `@tag:${REQUIRE_TRUSTED_WORKSPACE_SETTING_TAG}`, `@${ID_SETTING_TAG}`, `@${EXTENSION_SETTING_TAG}`, `@${FEATURE_SETTING_TAG}scm`, `@${FEATURE_SETTING_TAG}explorer`, `@${FEATURE_SETTING_TAG}search`, `@${FEATURE_SETTING_TAG}debug`, `@${FEATURE_SETTING_TAG}extensions`, `@${FEATURE_SETTING_TAG}terminal`, `@${FEATURE_SETTING_TAG}task`, `@${FEATURE_SETTING_TAG}problems`, `@${FEATURE_SETTING_TAG}output`, `@${FEATURE_SETTING_TAG}comments`, `@${FEATURE_SETTING_TAG}remote`, `@${FEATURE_SETTING_TAG}timeline`
`@${MODIFIED_SETTING_TAG}`,
'@tag:usesOnlineServices',
'@tag:sync',
`@tag:${REQUIRE_TRUSTED_WORKSPACE_SETTING_TAG}`,
`@${ID_SETTING_TAG}`,
`@${EXTENSION_SETTING_TAG}`,
`@${FEATURE_SETTING_TAG}scm`,
`@${FEATURE_SETTING_TAG}explorer`,
`@${FEATURE_SETTING_TAG}search`,
`@${FEATURE_SETTING_TAG}debug`,
`@${FEATURE_SETTING_TAG}extensions`,
`@${FEATURE_SETTING_TAG}terminal`,
`@${FEATURE_SETTING_TAG}task`,
`@${FEATURE_SETTING_TAG}problems`,
`@${FEATURE_SETTING_TAG}output`,
`@${FEATURE_SETTING_TAG}comments`,
`@${FEATURE_SETTING_TAG}remote`,
`@${FEATURE_SETTING_TAG}timeline`,
`@${FEATURE_SETTING_TAG}notebook`,
];
private static shouldSettingUpdateFast(type: SettingValueType | SettingValueType[]): boolean {

View file

@ -701,7 +701,7 @@ export class SearchResultModel extends SettingsTreeModel {
const isRemote = !!this.environmentService.remoteAuthority;
this.root.children = this.root.children
.filter(child => child instanceof SettingsTreeSettingElement && child.matchesAllTags(this._viewState.tagFilters) && child.matchesScope(this._viewState.settingsTarget, isRemote) && child.matchesAnyExtension(this._viewState.extensionFilters) && child.matchesAnyId(this._viewState.idFilters) && (this.containsValidFeature() ? child.matchesAnyFeature(this._viewState.featureFilters) : true));
.filter(child => child instanceof SettingsTreeSettingElement && child.matchesAllTags(this._viewState.tagFilters) && child.matchesScope(this._viewState.settingsTarget, isRemote) && child.matchesAnyExtension(this._viewState.extensionFilters) && child.matchesAnyId(this._viewState.idFilters) && (this.containsValidFeature() ? child.matchesAnyFeature(this._viewState.featureFilters) : false));
if (this.newExtensionSearchResults && this.newExtensionSearchResults.filterMatches.length) {
const resultExtensionIds = this.newExtensionSearchResults.filterMatches

View file

@ -5,7 +5,8 @@
import * as assert from 'assert';
import { MarkdownString } from 'vs/workbench/api/common/extHostTypeConverters';
import * as extHostTypes from 'vs/workbench/api/common/extHostTypes';
import { MarkdownString, NotebookCellOutputItem } from 'vs/workbench/api/common/extHostTypeConverters';
import { isEmptyObject } from 'vs/base/common/types';
import { forEach } from 'vs/base/common/collections';
import { LogLevel as _MainLogLevel } from 'vs/platform/log/common/log';
@ -81,4 +82,23 @@ suite('ExtHostTypeConverter', function () {
}
});
});
test('NotebookCellOutputItem', function () {
const item = extHostTypes.NotebookCellOutputItem.text('Hello', 'foo/bar');
const dto = NotebookCellOutputItem.from(item);
assert.strictEqual(dto.mime, 'foo/bar');
assert.strictEqual(dto.metadata, undefined);
assert.strictEqual(dto.value, undefined);
assert.deepStrictEqual(dto.valueBytes, Array.from(new TextEncoder().encode('Hello')));
const item2 = NotebookCellOutputItem.to(dto);
assert.strictEqual(item2.mime, item.mime);
assert.strictEqual(item2.metadata, item.metadata);
assert.strictEqual(item2.value, item.value);
assert.deepStrictEqual(item2.data, item.data);
});
});