mirror of
https://github.com/microsoft/vscode.git
synced 2026-09-21 21:57:49 +01:00
move cell output element to its own module
This commit is contained in:
@@ -0,0 +1,237 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as DOM from 'vs/base/browser/dom';
|
||||
import * as nls from 'vs/nls';
|
||||
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
import { KeyCode } from 'vs/base/common/keyCodes';
|
||||
import { Disposable, DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { IQuickPickItem, IQuickInputService } from 'vs/platform/quickinput/common/quickInput';
|
||||
import { INotebookEditor } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
|
||||
import { getResizesObserver } from 'vs/workbench/contrib/notebook/browser/view/renderers/cellWidgets';
|
||||
import { CodeCellViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/codeCellViewModel';
|
||||
import { ITransformedDisplayOutputDto, IRenderOutput, IProcessedOutput, RENDERER_NOT_AVAILABLE, BUILTIN_RENDERER_ID, RenderOutputType, outputHasDynamicHeight, CellUri, CellOutputKind } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
import { INotebookService } from 'vs/workbench/contrib/notebook/common/notebookService';
|
||||
|
||||
interface IMimeTypeRenderer extends IQuickPickItem {
|
||||
index: number;
|
||||
}
|
||||
|
||||
export class OutputElement extends Disposable {
|
||||
|
||||
// this isn't super proper but I couldn't find a view-model equivalent for output
|
||||
// and it seems as of today we use the domain model - and pragamtically enrich it
|
||||
// with UX properties
|
||||
private pickedMimeTypes = new WeakMap<ITransformedDisplayOutputDto, number>();
|
||||
|
||||
readonly resizeListener = new DisposableStore();
|
||||
domNode!: HTMLElement;
|
||||
renderResult?: IRenderOutput;
|
||||
|
||||
constructor(
|
||||
private notebookEditor: INotebookEditor,
|
||||
private notebookService: INotebookService,
|
||||
private quickInputService: IQuickInputService,
|
||||
private viewCell: CodeCellViewModel,
|
||||
private outputContainer: HTMLElement,
|
||||
readonly output: IProcessedOutput
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
render(index: number, beforeElement?: HTMLElement) {
|
||||
if (this.viewCell.metadata.outputCollapsed) {
|
||||
return;
|
||||
}
|
||||
|
||||
const outputItemDiv = document.createElement('div');
|
||||
let result: IRenderOutput | undefined = undefined;
|
||||
|
||||
if (this.output.outputKind === CellOutputKind.Rich) {
|
||||
const transformedDisplayOutput = this.output as ITransformedDisplayOutputDto;
|
||||
|
||||
const mimeTypes = this.notebookService.getMimeTypeInfo(this.notebookEditor.textModel!, this.output);
|
||||
|
||||
const pick = this.pickedMimeTypes.get(this.output) ?? Math.max(mimeTypes.findIndex(mimeType => mimeType.rendererId !== RENDERER_NOT_AVAILABLE), 0);
|
||||
|
||||
if (mimeTypes.length > 1) {
|
||||
outputItemDiv.style.position = 'relative';
|
||||
const mimeTypePicker = DOM.$('.multi-mimetype-output');
|
||||
mimeTypePicker.classList.add('codicon', 'codicon-code');
|
||||
mimeTypePicker.tabIndex = 0;
|
||||
mimeTypePicker.title = nls.localize('mimeTypePicker', "Choose a different output mimetype, available mimetypes: {0}", mimeTypes.map(mimeType => mimeType.mimeType).join(', '));
|
||||
outputItemDiv.appendChild(mimeTypePicker);
|
||||
this.resizeListener.add(DOM.addStandardDisposableListener(mimeTypePicker, 'mousedown', async e => {
|
||||
if (e.leftButton) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
await this.pickActiveMimeTypeRenderer(transformedDisplayOutput);
|
||||
}
|
||||
}));
|
||||
|
||||
this.resizeListener.add((DOM.addDisposableListener(mimeTypePicker, DOM.EventType.KEY_DOWN, async e => {
|
||||
const event = new StandardKeyboardEvent(e);
|
||||
if ((event.equals(KeyCode.Enter) || event.equals(KeyCode.Space))) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
await this.pickActiveMimeTypeRenderer(transformedDisplayOutput);
|
||||
}
|
||||
})));
|
||||
|
||||
}
|
||||
const pickedMimeTypeRenderer = mimeTypes[pick];
|
||||
|
||||
const innerContainer = DOM.$('.output-inner-container');
|
||||
DOM.append(outputItemDiv, innerContainer);
|
||||
|
||||
|
||||
if (pickedMimeTypeRenderer.rendererId !== BUILTIN_RENDERER_ID) {
|
||||
const renderer = this.notebookService.getRendererInfo(pickedMimeTypeRenderer.rendererId);
|
||||
result = renderer
|
||||
? { type: RenderOutputType.Extension, renderer, source: this.output, mimeType: pickedMimeTypeRenderer.mimeType }
|
||||
: this.notebookEditor.getOutputRenderer().render(this.output, innerContainer, pickedMimeTypeRenderer.mimeType, this.getNotebookUri(),);
|
||||
} else {
|
||||
result = this.notebookEditor.getOutputRenderer().render(this.output, innerContainer, pickedMimeTypeRenderer.mimeType, this.getNotebookUri(),);
|
||||
}
|
||||
} else {
|
||||
// for text and error, there is no mimetype
|
||||
const innerContainer = DOM.$('.output-inner-container');
|
||||
DOM.append(outputItemDiv, innerContainer);
|
||||
|
||||
result = this.notebookEditor.getOutputRenderer().render(this.output, innerContainer, undefined, this.getNotebookUri(),);
|
||||
}
|
||||
|
||||
this.domNode = outputItemDiv;
|
||||
this.renderResult = result;
|
||||
|
||||
if (!result) {
|
||||
this.viewCell.updateOutputHeight(index, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (beforeElement) {
|
||||
this.outputContainer.insertBefore(outputItemDiv, beforeElement);
|
||||
} else {
|
||||
this.outputContainer.appendChild(outputItemDiv);
|
||||
}
|
||||
|
||||
if (result.type !== RenderOutputType.None) {
|
||||
this.viewCell.selfSizeMonitoring = true;
|
||||
this.notebookEditor.createInset(this.viewCell, result as any, this.viewCell.getOutputOffset(index));
|
||||
} else {
|
||||
outputItemDiv.classList.add('foreground', 'output-element');
|
||||
outputItemDiv.style.position = 'absolute';
|
||||
}
|
||||
|
||||
if (outputHasDynamicHeight(result)) {
|
||||
this.viewCell.selfSizeMonitoring = true;
|
||||
|
||||
const clientHeight = outputItemDiv.clientHeight;
|
||||
const dimension = {
|
||||
width: this.viewCell.layoutInfo.editorWidth,
|
||||
height: clientHeight
|
||||
};
|
||||
const elementSizeObserver = getResizesObserver(outputItemDiv, dimension, () => {
|
||||
if (this.outputContainer && document.body.contains(this.outputContainer!)) {
|
||||
const height = Math.ceil(elementSizeObserver.getHeight());
|
||||
|
||||
if (clientHeight === height) {
|
||||
return;
|
||||
}
|
||||
|
||||
const currIndex = this.viewCell.outputs.indexOf(this.output);
|
||||
if (currIndex < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.viewCell.updateOutputHeight(currIndex, height);
|
||||
this.relayoutCell();
|
||||
}
|
||||
});
|
||||
elementSizeObserver.startObserving();
|
||||
this.resizeListener.add(elementSizeObserver);
|
||||
this.viewCell.updateOutputHeight(index, clientHeight);
|
||||
} else if (result.type === RenderOutputType.None) { // no-op if it's a webview
|
||||
const clientHeight = Math.ceil(outputItemDiv.clientHeight);
|
||||
this.viewCell.updateOutputHeight(index, clientHeight);
|
||||
|
||||
const top = this.viewCell.getOutputOffsetInContainer(index);
|
||||
outputItemDiv.style.top = `${top}px`;
|
||||
}
|
||||
}
|
||||
|
||||
async pickActiveMimeTypeRenderer(output: ITransformedDisplayOutputDto) {
|
||||
|
||||
const mimeTypes = this.notebookService.getMimeTypeInfo(this.notebookEditor.textModel!, output);
|
||||
const currIndex = this.pickedMimeTypes.get(output) ?? 0;
|
||||
|
||||
// const currIndex = output.pickedMimeTypeIndex;
|
||||
const items = mimeTypes.map((mimeType, index): IMimeTypeRenderer => ({
|
||||
label: mimeType.mimeType,
|
||||
id: mimeType.mimeType,
|
||||
index: index,
|
||||
picked: index === currIndex,
|
||||
detail: this.generateRendererInfo(mimeType.rendererId),
|
||||
description: index === currIndex ? nls.localize('curruentActiveMimeType', "Currently Active") : undefined
|
||||
}));
|
||||
|
||||
const picker = this.quickInputService.createQuickPick();
|
||||
picker.items = items;
|
||||
picker.activeItems = items.filter(item => !!item.picked);
|
||||
picker.placeholder = nls.localize('promptChooseMimeType.placeHolder', "Select output mimetype to render for current output");
|
||||
|
||||
const pick = await new Promise<number | undefined>(resolve => {
|
||||
picker.onDidAccept(() => {
|
||||
resolve(picker.selectedItems.length === 1 ? (picker.selectedItems[0] as IMimeTypeRenderer).index : undefined);
|
||||
picker.dispose();
|
||||
});
|
||||
picker.show();
|
||||
});
|
||||
|
||||
if (pick === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (pick !== currIndex) {
|
||||
// user chooses another mimetype
|
||||
const index = this.viewCell.outputs.indexOf(output);
|
||||
const nextElement = this.domNode.nextElementSibling;
|
||||
this.resizeListener.clear();
|
||||
const element = this.domNode;
|
||||
if (element) {
|
||||
element.parentElement?.removeChild(element);
|
||||
this.notebookEditor.removeInset(output);
|
||||
}
|
||||
|
||||
this.pickedMimeTypes.set(output, pick);
|
||||
this.render(index, nextElement as HTMLElement);
|
||||
this.relayoutCell();
|
||||
}
|
||||
}
|
||||
|
||||
private getNotebookUri(): URI | undefined {
|
||||
return CellUri.parse(this.viewCell.uri)?.notebook;
|
||||
}
|
||||
|
||||
generateRendererInfo(renderId: string | undefined): string {
|
||||
if (renderId === undefined || renderId === BUILTIN_RENDERER_ID) {
|
||||
return nls.localize('builtinRenderInfo', "built-in");
|
||||
}
|
||||
|
||||
const renderInfo = this.notebookService.getRendererInfo(renderId);
|
||||
|
||||
if (renderInfo) {
|
||||
const displayName = renderInfo.displayName !== '' ? renderInfo.displayName : renderInfo.id;
|
||||
return `${displayName} (${renderInfo.extensionId.value})`;
|
||||
}
|
||||
|
||||
return nls.localize('builtinRenderInfo', "built-in");
|
||||
}
|
||||
|
||||
relayoutCell() {
|
||||
this.notebookEditor.layoutNotebookCell(this.viewCell, this.viewCell.layoutInfo.totalHeight);
|
||||
}
|
||||
}
|
||||
@@ -4,249 +4,27 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as DOM from 'vs/base/browser/dom';
|
||||
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
import { renderMarkdown } from 'vs/base/browser/markdownRenderer';
|
||||
import { raceCancellation } from 'vs/base/common/async';
|
||||
import { CancellationTokenSource } from 'vs/base/common/cancellation';
|
||||
import { IMarkdownString } from 'vs/base/common/htmlContent';
|
||||
import { KeyCode } from 'vs/base/common/keyCodes';
|
||||
import { Disposable, DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { IDimension } from 'vs/editor/common/editorCommon';
|
||||
import { format } from 'vs/base/common/jsonFormatter';
|
||||
import { applyEdits } from 'vs/base/common/jsonEdit';
|
||||
import { IModeService } from 'vs/editor/common/services/modeService';
|
||||
import * as nls from 'vs/nls';
|
||||
import { IOpenerService } from 'vs/platform/opener/common/opener';
|
||||
import { IQuickInputService, IQuickPickItem } from 'vs/platform/quickinput/common/quickInput';
|
||||
import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput';
|
||||
import { EDITOR_BOTTOM_PADDING, EDITOR_TOP_PADDING } from 'vs/workbench/contrib/notebook/browser/constants';
|
||||
import { CellFocusMode, CodeCellRenderTemplate, INotebookEditor } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
|
||||
import { CodeCellViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/codeCellViewModel';
|
||||
import { BUILTIN_RENDERER_ID, CellOutputKind, CellUri, IInsetRenderOutput, IProcessedOutput, IRenderOutput, ITransformedDisplayOutputDto, NotebookCellOutputsSplice, outputHasDynamicHeight, RENDERER_NOT_AVAILABLE, RenderOutputType } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
import { CellOutputKind, IInsetRenderOutput, IProcessedOutput, NotebookCellOutputsSplice, RenderOutputType } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
import { INotebookService } from 'vs/workbench/contrib/notebook/common/notebookService';
|
||||
import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles';
|
||||
import { ClickTargetType, getResizesObserver } from 'vs/workbench/contrib/notebook/browser/view/renderers/cellWidgets';
|
||||
import { ClickTargetType } from 'vs/workbench/contrib/notebook/browser/view/renderers/cellWidgets';
|
||||
import { OutputElement } from 'vs/workbench/contrib/notebook/browser/view/renderers/cellOutput';
|
||||
|
||||
const OUTPUT_COUNT_LIMIT = 500;
|
||||
interface IMimeTypeRenderer extends IQuickPickItem {
|
||||
index: number;
|
||||
}
|
||||
|
||||
class OutputElement extends Disposable {
|
||||
|
||||
// this isn't super proper but I couldn't find a view-model equivalent for output
|
||||
// and it seems as of today we use the domain model - and pragamtically enrich it
|
||||
// with UX properties
|
||||
private pickedMimeTypes = new WeakMap<ITransformedDisplayOutputDto, number>();
|
||||
|
||||
readonly resizeListener = new DisposableStore();
|
||||
domNode!: HTMLElement;
|
||||
renderResult?: IRenderOutput;
|
||||
|
||||
constructor(
|
||||
private notebookEditor: INotebookEditor,
|
||||
private notebookService: INotebookService,
|
||||
private quickInputService: IQuickInputService,
|
||||
private viewCell: CodeCellViewModel,
|
||||
private outputContainer: HTMLElement,
|
||||
readonly output: IProcessedOutput
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
render(index: number, beforeElement?: HTMLElement) {
|
||||
if (this.viewCell.metadata.outputCollapsed) {
|
||||
return;
|
||||
}
|
||||
|
||||
const outputItemDiv = document.createElement('div');
|
||||
let result: IRenderOutput | undefined = undefined;
|
||||
|
||||
if (this.output.outputKind === CellOutputKind.Rich) {
|
||||
const transformedDisplayOutput = this.output as ITransformedDisplayOutputDto;
|
||||
|
||||
const mimeTypes = this.notebookService.getMimeTypeInfo(this.notebookEditor.textModel!, this.output);
|
||||
|
||||
const pick = this.pickedMimeTypes.get(this.output) ?? Math.max(mimeTypes.findIndex(mimeType => mimeType.rendererId !== RENDERER_NOT_AVAILABLE), 0);
|
||||
|
||||
if (mimeTypes.length > 1) {
|
||||
outputItemDiv.style.position = 'relative';
|
||||
const mimeTypePicker = DOM.$('.multi-mimetype-output');
|
||||
mimeTypePicker.classList.add('codicon', 'codicon-code');
|
||||
mimeTypePicker.tabIndex = 0;
|
||||
mimeTypePicker.title = nls.localize('mimeTypePicker', "Choose a different output mimetype, available mimetypes: {0}", mimeTypes.map(mimeType => mimeType.mimeType).join(', '));
|
||||
outputItemDiv.appendChild(mimeTypePicker);
|
||||
this.resizeListener.add(DOM.addStandardDisposableListener(mimeTypePicker, 'mousedown', async e => {
|
||||
if (e.leftButton) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
await this.pickActiveMimeTypeRenderer(transformedDisplayOutput);
|
||||
}
|
||||
}));
|
||||
|
||||
this.resizeListener.add((DOM.addDisposableListener(mimeTypePicker, DOM.EventType.KEY_DOWN, async e => {
|
||||
const event = new StandardKeyboardEvent(e);
|
||||
if ((event.equals(KeyCode.Enter) || event.equals(KeyCode.Space))) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
await this.pickActiveMimeTypeRenderer(transformedDisplayOutput);
|
||||
}
|
||||
})));
|
||||
|
||||
}
|
||||
const pickedMimeTypeRenderer = mimeTypes[pick];
|
||||
|
||||
const innerContainer = DOM.$('.output-inner-container');
|
||||
DOM.append(outputItemDiv, innerContainer);
|
||||
|
||||
|
||||
if (pickedMimeTypeRenderer.rendererId !== BUILTIN_RENDERER_ID) {
|
||||
const renderer = this.notebookService.getRendererInfo(pickedMimeTypeRenderer.rendererId);
|
||||
result = renderer
|
||||
? { type: RenderOutputType.Extension, renderer, source: this.output, mimeType: pickedMimeTypeRenderer.mimeType }
|
||||
: this.notebookEditor.getOutputRenderer().render(this.output, innerContainer, pickedMimeTypeRenderer.mimeType, this.getNotebookUri(),);
|
||||
} else {
|
||||
result = this.notebookEditor.getOutputRenderer().render(this.output, innerContainer, pickedMimeTypeRenderer.mimeType, this.getNotebookUri(),);
|
||||
}
|
||||
} else {
|
||||
// for text and error, there is no mimetype
|
||||
const innerContainer = DOM.$('.output-inner-container');
|
||||
DOM.append(outputItemDiv, innerContainer);
|
||||
|
||||
result = this.notebookEditor.getOutputRenderer().render(this.output, innerContainer, undefined, this.getNotebookUri(),);
|
||||
}
|
||||
|
||||
this.domNode = outputItemDiv;
|
||||
this.renderResult = result;
|
||||
|
||||
if (!result) {
|
||||
this.viewCell.updateOutputHeight(index, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (beforeElement) {
|
||||
this.outputContainer.insertBefore(outputItemDiv, beforeElement);
|
||||
} else {
|
||||
this.outputContainer.appendChild(outputItemDiv);
|
||||
}
|
||||
|
||||
if (result.type !== RenderOutputType.None) {
|
||||
this.viewCell.selfSizeMonitoring = true;
|
||||
this.notebookEditor.createInset(this.viewCell, result as any, this.viewCell.getOutputOffset(index));
|
||||
} else {
|
||||
outputItemDiv.classList.add('foreground', 'output-element');
|
||||
outputItemDiv.style.position = 'absolute';
|
||||
}
|
||||
|
||||
if (outputHasDynamicHeight(result)) {
|
||||
this.viewCell.selfSizeMonitoring = true;
|
||||
|
||||
const clientHeight = outputItemDiv.clientHeight;
|
||||
const dimension = {
|
||||
width: this.viewCell.layoutInfo.editorWidth,
|
||||
height: clientHeight
|
||||
};
|
||||
const elementSizeObserver = getResizesObserver(outputItemDiv, dimension, () => {
|
||||
if (this.outputContainer && document.body.contains(this.outputContainer!)) {
|
||||
const height = Math.ceil(elementSizeObserver.getHeight());
|
||||
|
||||
if (clientHeight === height) {
|
||||
return;
|
||||
}
|
||||
|
||||
const currIndex = this.viewCell.outputs.indexOf(this.output);
|
||||
if (currIndex < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.viewCell.updateOutputHeight(currIndex, height);
|
||||
this.relayoutCell();
|
||||
}
|
||||
});
|
||||
elementSizeObserver.startObserving();
|
||||
this.resizeListener.add(elementSizeObserver);
|
||||
this.viewCell.updateOutputHeight(index, clientHeight);
|
||||
} else if (result.type === RenderOutputType.None) { // no-op if it's a webview
|
||||
const clientHeight = Math.ceil(outputItemDiv.clientHeight);
|
||||
this.viewCell.updateOutputHeight(index, clientHeight);
|
||||
|
||||
const top = this.viewCell.getOutputOffsetInContainer(index);
|
||||
outputItemDiv.style.top = `${top}px`;
|
||||
}
|
||||
}
|
||||
|
||||
async pickActiveMimeTypeRenderer(output: ITransformedDisplayOutputDto) {
|
||||
|
||||
const mimeTypes = this.notebookService.getMimeTypeInfo(this.notebookEditor.textModel!, output);
|
||||
const currIndex = this.pickedMimeTypes.get(output) ?? 0;
|
||||
|
||||
// const currIndex = output.pickedMimeTypeIndex;
|
||||
const items = mimeTypes.map((mimeType, index): IMimeTypeRenderer => ({
|
||||
label: mimeType.mimeType,
|
||||
id: mimeType.mimeType,
|
||||
index: index,
|
||||
picked: index === currIndex,
|
||||
detail: this.generateRendererInfo(mimeType.rendererId),
|
||||
description: index === currIndex ? nls.localize('curruentActiveMimeType', "Currently Active") : undefined
|
||||
}));
|
||||
|
||||
const picker = this.quickInputService.createQuickPick();
|
||||
picker.items = items;
|
||||
picker.activeItems = items.filter(item => !!item.picked);
|
||||
picker.placeholder = nls.localize('promptChooseMimeType.placeHolder', "Select output mimetype to render for current output");
|
||||
|
||||
const pick = await new Promise<number | undefined>(resolve => {
|
||||
picker.onDidAccept(() => {
|
||||
resolve(picker.selectedItems.length === 1 ? (picker.selectedItems[0] as IMimeTypeRenderer).index : undefined);
|
||||
picker.dispose();
|
||||
});
|
||||
picker.show();
|
||||
});
|
||||
|
||||
if (pick === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (pick !== currIndex) {
|
||||
// user chooses another mimetype
|
||||
const index = this.viewCell.outputs.indexOf(output);
|
||||
const nextElement = this.domNode.nextElementSibling;
|
||||
this.resizeListener.clear();
|
||||
const element = this.domNode;
|
||||
if (element) {
|
||||
element.parentElement?.removeChild(element);
|
||||
this.notebookEditor.removeInset(output);
|
||||
}
|
||||
|
||||
this.pickedMimeTypes.set(output, pick);
|
||||
this.render(index, nextElement as HTMLElement);
|
||||
this.relayoutCell();
|
||||
}
|
||||
}
|
||||
|
||||
private getNotebookUri(): URI | undefined {
|
||||
return CellUri.parse(this.viewCell.uri)?.notebook;
|
||||
}
|
||||
|
||||
generateRendererInfo(renderId: string | undefined): string {
|
||||
if (renderId === undefined || renderId === BUILTIN_RENDERER_ID) {
|
||||
return nls.localize('builtinRenderInfo', "built-in");
|
||||
}
|
||||
|
||||
const renderInfo = this.notebookService.getRendererInfo(renderId);
|
||||
|
||||
if (renderInfo) {
|
||||
const displayName = renderInfo.displayName !== '' ? renderInfo.displayName : renderInfo.id;
|
||||
return `${displayName} (${renderInfo.extensionId.value})`;
|
||||
}
|
||||
|
||||
return nls.localize('builtinRenderInfo', "built-in");
|
||||
}
|
||||
|
||||
relayoutCell() {
|
||||
this.notebookEditor.layoutNotebookCell(this.viewCell, this.viewCell.layoutInfo.totalHeight);
|
||||
}
|
||||
}
|
||||
|
||||
export class CodeCell extends Disposable {
|
||||
private outputEntries = new Map<IProcessedOutput, OutputElement>();
|
||||
|
||||
Reference in New Issue
Block a user