Remove inputCollapsed and outputCollapsed metadata, make them view properties

Fix #125274
This commit is contained in:
Rob Lourens 2021-11-03 17:21:47 -07:00
parent 2f1e5cb85f
commit a14ebdfec4
19 changed files with 165 additions and 183 deletions

View file

@ -33,8 +33,6 @@ export function activate(context: vscode.ExtensionContext) {
transientOutputs: false,
transientCellMetadata: {
breakpointMargin: true,
inputCollapsed: true,
outputCollapsed: true,
custom: false
}
}));

View file

@ -5,20 +5,19 @@
import { KeyChord, KeyCode, KeyMod } from 'vs/base/common/keyCodes';
import { Mimes } from 'vs/base/common/mime';
import { IBulkEditService, ResourceTextEdit } from 'vs/editor/browser/services/bulkEditService';
import { localize } from 'vs/nls';
import { MenuId, registerAction2 } from 'vs/platform/actions/common/actions';
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
import { InputFocusedContext, InputFocusedContextKey } from 'vs/platform/contextkey/common/contextkeys';
import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
import { cellExecutionArgs, CellOverflowToolbarGroups, CellToolbarOrder, CELL_TITLE_CELL_GROUP_ID, INotebookCellActionContext, INotebookCellToolbarActionContext, INotebookCommandContext, NotebookCellAction, NotebookMultiCellAction, parseMultiCellExecutionArgs } from 'vs/workbench/contrib/notebook/browser/controller/coreActions';
import { CellFocusMode, EXPAND_CELL_INPUT_COMMAND_ID, EXPAND_CELL_OUTPUT_COMMAND_ID, NOTEBOOK_CELL_EDITABLE, NOTEBOOK_CELL_HAS_OUTPUTS, NOTEBOOK_CELL_INPUT_COLLAPSED, NOTEBOOK_CELL_LIST_FOCUSED, NOTEBOOK_CELL_OUTPUT_COLLAPSED, NOTEBOOK_CELL_TYPE, NOTEBOOK_EDITOR_EDITABLE, NOTEBOOK_EDITOR_FOCUSED, NOTEBOOK_IS_ACTIVE_EDITOR } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
import * as icons from 'vs/workbench/contrib/notebook/browser/notebookIcons';
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
import { CellEditType, CellKind, ICellEditOperation, NotebookCellMetadata } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { IBulkEditService, ResourceTextEdit } from 'vs/editor/browser/services/bulkEditService';
import { changeCellToKind, computeCellLinesContents, copyCellRange, joinCellsWithSurrounds, moveCellRange } from 'vs/workbench/contrib/notebook/browser/controller/cellOperations';
import { NotebookCellTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookCellTextModel';
import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
import { ResourceNotebookCellEdit } from 'vs/workbench/contrib/bulkEdit/browser/bulkCellEdits';
import { changeCellToKind, computeCellLinesContents, copyCellRange, joinCellsWithSurrounds, moveCellRange } from 'vs/workbench/contrib/notebook/browser/controller/cellOperations';
import { cellExecutionArgs, CellOverflowToolbarGroups, CellToolbarOrder, CELL_TITLE_CELL_GROUP_ID, INotebookCellActionContext, INotebookCellToolbarActionContext, INotebookCommandContext, NotebookCellAction, NotebookMultiCellAction, parseMultiCellExecutionArgs } from 'vs/workbench/contrib/notebook/browser/controller/coreActions';
import { CellFocusMode, EXPAND_CELL_INPUT_COMMAND_ID, EXPAND_CELL_OUTPUT_COMMAND_ID, ICellViewModel, NOTEBOOK_CELL_EDITABLE, NOTEBOOK_CELL_HAS_OUTPUTS, NOTEBOOK_CELL_INPUT_COLLAPSED, NOTEBOOK_CELL_LIST_FOCUSED, NOTEBOOK_CELL_OUTPUT_COLLAPSED, NOTEBOOK_CELL_TYPE, NOTEBOOK_EDITOR_EDITABLE, NOTEBOOK_EDITOR_FOCUSED, NOTEBOOK_IS_ACTIVE_EDITOR } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
import * as icons from 'vs/workbench/contrib/notebook/browser/notebookIcons';
import { CellEditType, CellKind } from 'vs/workbench/contrib/notebook/common/notebookCommon';
//#region Move/Copy cells
const MOVE_CELL_UP_COMMAND_ID = 'notebook.cell.moveUp';
@ -322,30 +321,7 @@ const COLLAPSE_CELL_INPUT_COMMAND_ID = 'notebook.cell.collapseCellInput';
const COLLAPSE_CELL_OUTPUT_COMMAND_ID = 'notebook.cell.collapseCellOutput';
const TOGGLE_CELL_OUTPUTS_COMMAND_ID = 'notebook.cell.toggleOutputs';
abstract class ChangeNotebookCellMetadataAction extends NotebookCellAction {
async runWithContext(accessor: ServicesAccessor, context: INotebookCellActionContext): Promise<void> {
const textModel = context.notebookEditor.textModel;
if (!textModel) {
return;
}
const metadataDelta = this.getMetadataDelta();
const edits: ICellEditOperation[] = [];
const targetCells = (context.cell ? [context.cell] : context.selectedCells) ?? [];
for (const cell of targetCells) {
const index = textModel.cells.indexOf(cell.model);
if (index >= 0) {
edits.push({ editType: CellEditType.Metadata, index, metadata: { ...context.cell.metadata, ...metadataDelta } });
}
}
textModel.applyEdits(edits, true, undefined, () => undefined, undefined);
}
abstract getMetadataDelta(): NotebookCellMetadata;
}
registerAction2(class CollapseCellInputAction extends ChangeNotebookCellMetadataAction {
registerAction2(class CollapseCellInputAction extends NotebookMultiCellAction {
constructor() {
super({
id: COLLAPSE_CELL_INPUT_COMMAND_ID,
@ -364,12 +340,16 @@ registerAction2(class CollapseCellInputAction extends ChangeNotebookCellMetadata
});
}
getMetadataDelta(): NotebookCellMetadata {
return { inputCollapsed: true };
async runWithContext(accessor: ServicesAccessor, context: INotebookCommandContext | INotebookCellToolbarActionContext): Promise<void> {
if (context.ui) {
context.cell.isInputCollapsed = true;
} else {
context.selectedCells.forEach(cell => cell.isInputCollapsed = true);
}
}
});
registerAction2(class ExpandCellInputAction extends ChangeNotebookCellMetadataAction {
registerAction2(class ExpandCellInputAction extends NotebookMultiCellAction {
constructor() {
super({
id: EXPAND_CELL_INPUT_COMMAND_ID,
@ -388,12 +368,16 @@ registerAction2(class ExpandCellInputAction extends ChangeNotebookCellMetadataAc
});
}
getMetadataDelta(): NotebookCellMetadata {
return { inputCollapsed: false };
async runWithContext(accessor: ServicesAccessor, context: INotebookCommandContext | INotebookCellToolbarActionContext): Promise<void> {
if (context.ui) {
context.cell.isInputCollapsed = false;
} else {
context.selectedCells.forEach(cell => cell.isInputCollapsed = false);
}
}
});
registerAction2(class CollapseCellOutputAction extends ChangeNotebookCellMetadataAction {
registerAction2(class CollapseCellOutputAction extends NotebookMultiCellAction {
constructor() {
super({
id: COLLAPSE_CELL_OUTPUT_COMMAND_ID,
@ -412,12 +396,16 @@ registerAction2(class CollapseCellOutputAction extends ChangeNotebookCellMetadat
});
}
getMetadataDelta(): NotebookCellMetadata {
return { outputCollapsed: true };
async runWithContext(accessor: ServicesAccessor, context: INotebookCommandContext | INotebookCellToolbarActionContext): Promise<void> {
if (context.ui) {
context.cell.isOutputCollapsed = true;
} else {
context.selectedCells.forEach(cell => cell.isOutputCollapsed = true);
}
}
});
registerAction2(class ExpandCellOuputAction extends ChangeNotebookCellMetadataAction {
registerAction2(class ExpandCellOuputAction extends NotebookMultiCellAction {
constructor() {
super({
id: EXPAND_CELL_OUTPUT_COMMAND_ID,
@ -436,8 +424,12 @@ registerAction2(class ExpandCellOuputAction extends ChangeNotebookCellMetadataAc
});
}
getMetadataDelta(): NotebookCellMetadata {
return { outputCollapsed: false };
async runWithContext(accessor: ServicesAccessor, context: INotebookCommandContext | INotebookCellToolbarActionContext): Promise<void> {
if (context.ui) {
context.cell.isOutputCollapsed = false;
} else {
context.selectedCells.forEach(cell => cell.isOutputCollapsed = false);
}
}
});
@ -459,25 +451,16 @@ registerAction2(class extends NotebookMultiCellAction {
}
async runWithContext(accessor: ServicesAccessor, context: INotebookCommandContext | INotebookCellToolbarActionContext): Promise<void> {
const textModel = context.notebookEditor.textModel;
let cells: NotebookCellTextModel[] = [];
let cells: readonly ICellViewModel[] = [];
if (context.ui) {
cells = [context.cell.model];
cells = [context.cell];
} else if (context.selectedCells) {
cells = context.selectedCells.map(cell => cell.model);
} else {
cells = [...textModel.cells];
cells = context.selectedCells;
}
const edits: ICellEditOperation[] = [];
for (const cell of cells) {
const index = textModel.cells.indexOf(cell);
if (index >= 0) {
edits.push({ editType: CellEditType.Metadata, index, metadata: { ...cell.metadata, outputCollapsed: !cell.metadata.outputCollapsed } });
}
for (let cell of cells) {
cell.isOutputCollapsed = !cell.isOutputCollapsed;
}
textModel.applyEdits(edits, true, undefined, () => undefined, undefined);
}
});

View file

@ -52,7 +52,7 @@ class NotebookViewportContribution extends Disposable implements INotebookEditor
for (let i = 0; i < this._notebookEditor.getLength(); i++) {
const cell = this._notebookEditor.cellAt(i);
if (cell?.cellKind === CellKind.Markup && cell?.getEditState() === CellEditState.Preview && !cell.metadata.inputCollapsed) {
if (cell?.cellKind === CellKind.Markup && cell?.getEditState() === CellEditState.Preview && !cell.isInputCollapsed) {
// TODO@rebornix currently we disable markdown cell rendering in webview for accessibility
// this._notebookEditor.createMarkupPreview(cell);
} else if (cell?.cellKind === CellKind.Code) {
@ -75,7 +75,7 @@ class NotebookViewportContribution extends Disposable implements INotebookEditor
cellRangesToIndexes(visibleRanges).forEach(index => {
const cell = this._notebookEditor.cellAt(index);
if (cell?.cellKind === CellKind.Markup && cell?.getEditState() === CellEditState.Preview && !cell.metadata.inputCollapsed) {
if (cell?.cellKind === CellKind.Markup && cell?.getEditState() === CellEditState.Preview && !cell.isInputCollapsed) {
(this._notebookEditor as INotebookEditorDelegate).createMarkupPreview(cell);
} else if (cell?.cellKind === CellKind.Code) {
this._renderCell((cell as CodeCellViewModel));
@ -84,7 +84,7 @@ class NotebookViewportContribution extends Disposable implements INotebookEditor
}
private _renderCell(viewCell: CodeCellViewModel) {
if (viewCell.metadata.outputCollapsed) {
if (viewCell.isOutputCollapsed) {
return;
}

View file

@ -461,14 +461,6 @@ class RegisterSchemasContribution extends Disposable implements IWorkbenchContri
['language']: {
type: 'string',
description: 'The language for the cell'
},
['inputCollapsed']: {
type: 'boolean',
description: `Whether a code cell's editor is collapsed`
},
['outputCollapsed']: {
type: 'boolean',
description: `Whether a code cell's outputs are collapsed`
}
},
// patternProperties: allSettings.patternProperties,

View file

@ -254,6 +254,8 @@ export interface ICellViewModel extends IGenericCellViewModel {
readonly onDidChangeCellStatusBarItems: Event<void>;
readonly editStateSource: string;
readonly editorAttached: boolean;
isInputCollapsed: boolean;
isOutputCollapsed: boolean;
dragging: boolean;
handle: number;
uri: URI;
@ -723,6 +725,8 @@ export interface CellViewModelStateChangeEvent {
readonly outputIsFocusedChanged?: boolean;
readonly cellIsHoveredChanged?: boolean;
readonly cellLineNumberChanged?: boolean;
readonly inputCollapsedChanged?: boolean;
readonly outputCollapsedChanged?: boolean;
}
export function getVisibleCells(cells: CellViewModel[], hiddenRanges: ICellRange[]) {

View file

@ -1423,17 +1423,17 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditorD
store.add((cell as CodeCellViewModel).onDidRemoveOutputs((outputs) => {
outputs.forEach(output => this.removeInset(output));
}));
store.add((cell as CodeCellViewModel).onDidHideOutputs((outputs) => {
outputs.forEach(output => this.hideInset(output));
}));
}
if (cell.cellKind === CellKind.Markup) {
store.add((cell as MarkupCellViewModel).onDidHideInput(() => {
store.add((cell as CellViewModel).onDidChangeState(e => {
if (e.inputCollapsedChanged && cell.isInputCollapsed && cell.cellKind === CellKind.Markup) {
this.hideMarkupPreviews([(cell as MarkupCellViewModel)]);
}));
}
}
if (e.outputCollapsedChanged && cell.isOutputCollapsed && cell.cellKind === CellKind.Code) {
cell.outputsViewModels.forEach(output => this.hideInset(output));
}
}));
return store;
}
@ -1576,7 +1576,9 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditorD
if (!state) {
return {
editingCells: {},
editorViewStates: {}
editorViewStates: {},
collapsedInputCells: {},
collapsedOutputCells: {},
};
}
@ -2319,7 +2321,7 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditorD
output: output.source,
cellTop,
outputOffset,
forceDisplay: !cell.metadata.outputCollapsed,
forceDisplay: !cell.isOutputCollapsed,
}], []);
}
});

View file

@ -180,7 +180,7 @@ export class NotebookCellList extends WorkbenchList<CellViewModel> implements ID
this._localDisposableStore.add(this.view.onMouseDblClick(() => {
const focus = this.getFocusedElements()[0];
if (focus && focus.cellKind === CellKind.Markup && !focus.metadata.inputCollapsed && !this._viewModel?.options.isReadOnly) {
if (focus && focus.cellKind === CellKind.Markup && !focus.isInputCollapsed && !this._viewModel?.options.isReadOnly) {
// scroll the cell into view if out of viewport
this.revealElementInView(focus);
focus.updateEditState(CellEditState.Editing, 'dbclick');

View file

@ -28,7 +28,7 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import { IWorkspaceTrustManagementService } from 'vs/platform/workspace/common/workspaceTrust';
import { asWebviewUri, webviewGenericCspSource } from 'vs/workbench/api/common/shared/webview';
import { CellEditState, ICellOutputViewModel, ICommonCellInfo, IDisplayOutputLayoutUpdateRequest, IDisplayOutputViewModel, IFocusNotebookCellOptions, IGenericCellViewModel, IInsetRenderOutput, INotebookEditorCreationOptions, RenderOutputType } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
import { CellEditState, ICellOutputViewModel, ICellViewModel, ICommonCellInfo, IDisplayOutputLayoutUpdateRequest, IDisplayOutputViewModel, IFocusNotebookCellOptions, IGenericCellViewModel, IInsetRenderOutput, INotebookEditorCreationOptions, RenderOutputType } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
import { preloadsScriptStr, RendererMetadata } from 'vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads';
import { transformWebviewThemeVars } from 'vs/workbench/contrib/notebook/browser/view/renderers/webviewThemeMapping';
import { MarkupCellViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/markupCellViewModel';
@ -836,7 +836,7 @@ var requirejs = (function() {
return false;
}
if (cell.metadata.outputCollapsed) {
if ('isOutputCollapsed' in cell && (cell as ICellViewModel).isOutputCollapsed) {
return false;
}

View file

@ -59,7 +59,6 @@ export class CellContextKeyManager extends Disposable {
this.elementDisposables.add(element.onDidChangeOutputs(() => this.updateForOutputs()));
}
this.elementDisposables.add(element.model.onDidChangeMetadata(() => this.updateForCollapseState()));
this.elementDisposables.add(this.notebookEditor.onDidChangeActiveCell(() => this.updateForFocusState()));
this.element = element;
@ -98,9 +97,9 @@ export class CellContextKeyManager extends Disposable {
this.cellLineNumbers.set(this.element.lineNumbers);
}
// if (e.collapseStateChanged) {
// this.updateForCollapseState();
// }
if (e.inputCollapsedChanged || e.outputCollapsedChanged) {
this.updateForCollapseState();
}
});
}
@ -151,8 +150,8 @@ export class CellContextKeyManager extends Disposable {
}
private updateForCollapseState() {
this.cellContentCollapsed.set(!!this.element.metadata.inputCollapsed);
this.cellOutputCollapsed.set(!!this.element.metadata.outputCollapsed);
this.cellContentCollapsed.set(!!this.element.isInputCollapsed);
this.cellOutputCollapsed.set(!!this.element.isOutputCollapsed);
}
private updateForOutputs() {

View file

@ -239,7 +239,7 @@ export class CellOutputElement extends Disposable {
render(previousSibling: HTMLElement | undefined, forceBreakStreaming: boolean = false): IRenderResult | undefined {
const index = this.viewCell.outputsViewModels.indexOf(this.output);
if (this.viewCell.metadata.outputCollapsed || !this.notebookEditor.hasModel()) {
if (this.viewCell.isOutputCollapsed || !this.notebookEditor.hasModel()) {
return undefined;
}

View file

@ -50,7 +50,7 @@ import { StatefulMarkdownCell } from 'vs/workbench/contrib/notebook/browser/view
import { CodeCellViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/codeCellViewModel';
import { MarkupCellViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/markupCellViewModel';
import { CellViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/notebookViewModel';
import { CellEditType, CellKind, NotebookCellExecutionState, NotebookCellInternalMetadata, NotebookCellMetadata } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { CellKind, NotebookCellExecutionState, NotebookCellInternalMetadata } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { NotebookOptions } from 'vs/workbench/contrib/notebook/common/notebookOptions';
const $ = DOM.$;
@ -408,7 +408,7 @@ export class MarkupCellRenderer extends AbstractCellRenderer implements IListRen
this.updateForHover(element, templateData);
}
if (e.metadataChanged) {
if (e.inputCollapsedChanged) {
this.updateCollapsedState(element);
}
@ -454,7 +454,7 @@ export class MarkupCellRenderer extends AbstractCellRenderer implements IListRen
}
private updateCollapsedState(element: MarkupCellViewModel) {
if (element.metadata.inputCollapsed) {
if (element.isInputCollapsed) {
this.notebookEditor.hideMarkupPreviews([element]);
} else {
this.notebookEditor.unhideMarkupPreviews([element]);
@ -755,9 +755,7 @@ export class CodeCellRenderer extends AbstractCellRenderer implements IListRende
return;
}
textModel.applyEdits([
{ editType: CellEditType.Metadata, index, metadata: { ...templateData.currentRenderedCell.metadata, outputCollapsed: !templateData.currentRenderedCell.metadata.outputCollapsed } }
], true, undefined, () => undefined, undefined);
templateData.currentRenderedCell.isOutputCollapsed = !templateData.currentRenderedCell.isOutputCollapsed;
};
templateData.disposables.add(DOM.addDisposableListener(expandIcon, DOM.EventType.CLICK, () => {
@ -777,17 +775,11 @@ export class CodeCellRenderer extends AbstractCellRenderer implements IListRende
}
const clickedOnInput = e.offsetY < (cell.layoutInfo as CodeCellLayoutInfo).outputContainerOffset;
const textModel = this.notebookEditor.textModel;
const metadata: Partial<NotebookCellMetadata> = clickedOnInput ?
{ inputCollapsed: !cell.metadata.inputCollapsed } :
{ outputCollapsed: !cell.metadata.outputCollapsed };
textModel.applyEdits([
{
editType: CellEditType.PartialMetadata,
index: this.notebookEditor.getCellIndex(cell),
metadata
}
], true, undefined, () => undefined, undefined);
if (clickedOnInput) {
cell.isInputCollapsed = !cell.isInputCollapsed;
} else {
cell.isOutputCollapsed = !cell.isOutputCollapsed;
}
});
const collapsedPartListener = DOM.addDisposableListener(templateData.cellInputCollapsedContainer, DOM.EventType.DBLCLICK, e => {
@ -796,18 +788,11 @@ export class CodeCellRenderer extends AbstractCellRenderer implements IListRende
return;
}
const metadata: Partial<NotebookCellMetadata> = cell.metadata.inputCollapsed ?
{ inputCollapsed: false } :
{ outputCollapsed: false };
const textModel = this.notebookEditor.textModel;
textModel.applyEdits([
{
editType: CellEditType.PartialMetadata,
index: this.notebookEditor.getCellIndex(cell),
metadata
}
], true, undefined, () => undefined, undefined);
if (cell.isInputCollapsed) {
cell.isInputCollapsed = false;
} else {
cell.isOutputCollapsed = false;
}
});
const clickHandler = DOM.addDisposableListener(templateData.cellInputCollapsedContainer, DOM.EventType.CLICK, e => {
@ -820,16 +805,7 @@ export class CodeCellRenderer extends AbstractCellRenderer implements IListRende
if (element && element.classList && element.classList.contains('expandInputIcon')) {
// clicked on the expand icon
const textModel = this.notebookEditor.textModel;
textModel.applyEdits([
{
editType: CellEditType.PartialMetadata,
index: this.notebookEditor.getCellIndex(cell),
metadata: {
inputCollapsed: false
}
}
], true, undefined, () => undefined, undefined);
cell.isInputCollapsed = false;
}
});
@ -910,14 +886,7 @@ export class CodeCellRenderer extends AbstractCellRenderer implements IListRende
const internalMetadata = element.internalMetadata;
this.updateExecutionOrder(internalMetadata, templateData);
if (element.metadata.inputCollapsed) {
templateData.progressBar.hide();
} else {
templateData.collapsedProgressBar.hide();
}
const progressBar = element.metadata.inputCollapsed ? templateData.collapsedProgressBar : templateData.progressBar;
const progressBar = element.isInputCollapsed ? templateData.collapsedProgressBar : templateData.progressBar;
if (internalMetadata.runState === NotebookCellExecutionState.Executing && !internalMetadata.isPaused) {
progressBar.infinite().show(500);
} else {
@ -1051,6 +1020,14 @@ export class CodeCellRenderer extends AbstractCellRenderer implements IListRende
if (e.cellLineNumberChanged) {
cellEditorOptions.setLineNumbers(element.lineNumbers);
}
if (e.inputCollapsedChanged) {
if (element.isInputCollapsed) {
templateData.progressBar.hide();
} else {
templateData.collapsedProgressBar.hide();
}
}
}));
this.updateForOutputs(element, templateData);

View file

@ -129,7 +129,9 @@ export class CodeCell extends Disposable {
this._register(viewCell.onDidChangeState((e) => {
if (e.metadataChanged || e.internalMetadataChanged) {
updateEditorOptions();
}
if (e.inputCollapsedChanged || e.outputCollapsedChanged) {
this.viewCell.pauseLayout();
const updated = this.updateForCollapseState();
this.viewCell.resumeLayout();
@ -249,7 +251,7 @@ export class CodeCell extends Disposable {
this._outputContainerRenderer = this.instantiationService.createInstance(CellOutputContainer, notebookEditor, viewCell, templateData, { limit: 500 });
this._outputContainerRenderer.render(editorHeight);
// Need to do this after the intial renderOutput
if (this.viewCell.metadata.outputCollapsed === undefined && this.viewCell.metadata.inputCollapsed === undefined) {
if (this.viewCell.isOutputCollapsed === undefined && this.viewCell.isInputCollapsed === undefined) {
this.initialViewUpdateExpanded();
this.viewCell.layoutChange({});
}
@ -262,20 +264,20 @@ export class CodeCell extends Disposable {
}
private updateForCollapseState(): boolean {
if (this.viewCell.metadata.outputCollapsed === this._renderedOutputCollapseState &&
this.viewCell.metadata.inputCollapsed === this._renderedInputCollapseState) {
if (this.viewCell.isOutputCollapsed === this._renderedOutputCollapseState &&
this.viewCell.isInputCollapsed === this._renderedInputCollapseState) {
return false;
}
this.viewCell.layoutChange({});
if (this.viewCell.metadata.inputCollapsed) {
if (this.viewCell.isInputCollapsed) {
this._collapseInput();
} else {
this._showInput();
}
if (this.viewCell.metadata.outputCollapsed) {
if (this.viewCell.isOutputCollapsed) {
this._collapseOutput();
} else {
this._showOutput(false);
@ -283,8 +285,8 @@ export class CodeCell extends Disposable {
this.relayoutCell();
this._renderedOutputCollapseState = this.viewCell.metadata.outputCollapsed;
this._renderedInputCollapseState = this.viewCell.metadata.inputCollapsed;
this._renderedOutputCollapseState = this.viewCell.isOutputCollapsed;
this._renderedInputCollapseState = this.viewCell.isInputCollapsed;
return true;
}

View file

@ -163,7 +163,7 @@ export class StatefulMarkdownCell extends Disposable {
}
private viewUpdate(): void {
if (this.viewCell.metadata.inputCollapsed) {
if (this.viewCell.isInputCollapsed) {
this.viewUpdateCollapsed();
} else if (this.viewCell.getEditState() === CellEditState.Editing) {
this.viewUpdateEditing();

View file

@ -150,6 +150,24 @@ export abstract class BaseCellViewModel extends Disposable {
protected _textModelRef: IReference<IResolvedTextEditorModel> | undefined;
private _inputCollapsed: boolean = false;
get isInputCollapsed(): boolean {
return this._inputCollapsed;
}
set isInputCollapsed(v: boolean) {
this._inputCollapsed = v;
this._onDidChangeState.fire({ inputCollapsedChanged: true });
}
private _outputCollapsed: boolean = false;
get isOutputCollapsed(): boolean {
return this._outputCollapsed;
}
set isOutputCollapsed(v: boolean) {
this._outputCollapsed = v;
this._onDidChangeState.fire({ outputCollapsedChanged: true });
}
constructor(
readonly viewType: string,
readonly model: NotebookCellTextModel,

View file

@ -32,12 +32,6 @@ export class CodeCellViewModel extends BaseCellViewModel implements ICellViewMod
private readonly _onDidRemoveOutputs = this._register(new Emitter<readonly ICellOutputViewModel[]>());
readonly onDidRemoveOutputs = this._onDidRemoveOutputs.event;
private readonly _onDidHideInput = this._register(new Emitter<void>());
readonly onDidHideInput = this._onDidHideInput.event;
private readonly _onDidHideOutputs = this._register(new Emitter<readonly ICellOutputViewModel[]>());
readonly onDidHideOutputs = this._onDidHideOutputs.event;
private _outputCollection: number[] = [];
private _outputsTop: PrefixSumComputer | null = null;
@ -130,16 +124,6 @@ export class CodeCellViewModel extends BaseCellViewModel implements ICellViewMod
dispose(removedOutputs);
}));
this._register(this.model.onDidChangeMetadata(e => {
if (this.metadata.outputCollapsed) {
this._onDidHideOutputs.fire(this.outputsViewModels.slice(0));
}
if (this.metadata.inputCollapsed) {
this._onDidHideInput.fire();
}
}));
this._outputCollection = new Array(this.model.outputs.length);
this._layoutInfo = {
@ -179,10 +163,10 @@ export class CodeCellViewModel extends BaseCellViewModel implements ICellViewMod
const notebookLayoutConfiguration = this.viewContext.notebookOptions.getLayoutConfiguration();
const bottomToolbarDimensions = this.viewContext.notebookOptions.computeBottomToolbarDimensions();
const outputShowMoreContainerHeight = state.outputShowMoreContainerHeight ? state.outputShowMoreContainerHeight : this._layoutInfo.outputShowMoreContainerHeight;
let outputTotalHeight = Math.max(this._outputMinHeight, this.metadata.outputCollapsed ? notebookLayoutConfiguration.collapsedIndicatorHeight : this._outputsTop!.getTotalSum());
let outputTotalHeight = Math.max(this._outputMinHeight, this.isOutputCollapsed ? notebookLayoutConfiguration.collapsedIndicatorHeight : this._outputsTop!.getTotalSum());
const originalLayout = this.layoutInfo;
if (!this.metadata.inputCollapsed) {
if (!this.isInputCollapsed) {
let newState: CellLayoutState;
let editorHeight: number;
let totalHeight: number;

View file

@ -100,9 +100,6 @@ export class MarkupCellViewModel extends BaseCellViewModel implements ICellViewM
this._onDidChangeState.fire({ cellIsHoveredChanged: true });
}
private readonly _onDidHideInput = this._register(new Emitter<void>());
readonly onDidHideInput = this._onDidHideInput.event;
constructor(
viewType: string,
model: NotebookCellTextModel,
@ -134,12 +131,6 @@ export class MarkupCellViewModel extends BaseCellViewModel implements ICellViewM
this._register(this.onDidChangeState(e => {
this.viewContext.eventDispatcher.emit([new NotebookCellStateChangedEvent(e, this)]);
}));
this._register(model.onDidChangeMetadata(e => {
if (this.metadata.inputCollapsed) {
this._onDidHideInput.fire();
}
}));
}
updateOptions(e: NotebookOptionsChangeEvent) {
@ -187,7 +178,7 @@ export class MarkupCellViewModel extends BaseCellViewModel implements ICellViewM
layoutChange(state: MarkdownCellLayoutChangeEvent) {
// recompute
if (!this.metadata.inputCollapsed) {
if (!this.isInputCollapsed) {
const editorWidth = state.outerWidth !== undefined
? this.viewContext.notebookOptions.computeMarkdownCellEditorWidth(state.outerWidth)
: this._layoutInfo.editorWidth;

View file

@ -35,6 +35,8 @@ import { cellIndexesToRanges, cellRangesToIndexes, ICellRange, reduceCellRanges
export interface INotebookEditorViewState {
editingCells: { [key: number]: boolean; };
collapsedInputCells: { [key: number]: boolean; };
collapsedOutputCells: { [key: number]: boolean; };
editorViewStates: { [key: number]: editorCommon.ICodeEditorViewState | null; };
hiddenFoldingRanges?: ICellRange[];
cellTotalHeights?: { [key: number]: number; };
@ -775,10 +777,21 @@ export class NotebookViewModel extends Disposable implements EditorFoldingStateD
getEditorViewState(): INotebookEditorViewState {
const editingCells: { [key: number]: boolean; } = {};
const collapsedInputCells: { [key: number]: boolean; } = {};
const collapsedOutputCells: { [key: number]: boolean; } = {};
this._viewCells.forEach((cell, i) => {
if (cell.getEditState() === CellEditState.Editing) {
editingCells[i] = true;
}
if (cell.isInputCollapsed) {
collapsedInputCells[i] = true;
}
if (cell instanceof CodeCellViewModel && cell.isOutputCollapsed) {
collapsedOutputCells[i] = true;
}
});
const editorViewStates: { [key: number]: editorCommon.ICodeEditorViewState; } = {};
this._viewCells.map(cell => ({ handle: cell.model.handle, state: cell.saveEditorViewState() })).forEach((viewState, i) => {
@ -790,6 +803,8 @@ export class NotebookViewModel extends Disposable implements EditorFoldingStateD
return {
editingCells,
editorViewStates,
collapsedInputCells,
collapsedOutputCells
};
}
@ -805,6 +820,12 @@ export class NotebookViewModel extends Disposable implements EditorFoldingStateD
cell.updateEditState(isEditing ? CellEditState.Editing : CellEditState.Preview, 'viewState');
const cellHeight = viewState.cellTotalHeights ? viewState.cellTotalHeights[index] : undefined;
cell.restoreEditorViewState(editorViewState, cellHeight);
if (viewState.collapsedInputCells && viewState.collapsedInputCells[index]) {
cell.isInputCollapsed = true;
}
if (viewState.collapsedOutputCells && viewState.collapsedOutputCells[index] && cell instanceof CodeCellViewModel) {
cell.isOutputCollapsed = true;
}
});
}

View file

@ -81,9 +81,6 @@ export interface INotebookCellPreviousExecutionResult {
}
export interface NotebookCellMetadata {
inputCollapsed?: boolean;
outputCollapsed?: boolean;
/**
* custom metadata
*/

View file

@ -40,7 +40,9 @@ suite('NotebookCellList', () => {
viewModel.restoreEditorViewState({
editingCells: [false, false, false, false, false],
editorViewStates: [null, null, null, null, null],
cellTotalHeights: [50, 100, 50, 100, 50]
cellTotalHeights: [50, 100, 50, 100, 50],
collapsedInputCells: {},
collapsedOutputCells: {},
});
const cellList = createNotebookCellList(instantiationService);
@ -84,7 +86,9 @@ suite('NotebookCellList', () => {
viewModel.restoreEditorViewState({
editingCells: [false, false, false, false, false],
editorViewStates: [null, null, null, null, null],
cellTotalHeights: [50, 100, 50, 100, 50]
cellTotalHeights: [50, 100, 50, 100, 50],
collapsedInputCells: {},
collapsedOutputCells: {},
});
const cellList = createNotebookCellList(instantiationService);
@ -125,7 +129,9 @@ suite('NotebookCellList', () => {
viewModel.restoreEditorViewState({
editingCells: [false, false, false, false, false],
editorViewStates: [null, null, null, null, null],
cellTotalHeights: [50, 100, 50, 100, 50]
cellTotalHeights: [50, 100, 50, 100, 50],
collapsedInputCells: {},
collapsedOutputCells: {},
});
const cellList = createNotebookCellList(instantiationService);
@ -159,7 +165,9 @@ suite('NotebookCellList', () => {
viewModel.restoreEditorViewState({
editingCells: [false, false, false, false, false],
editorViewStates: [null, null, null, null, null],
cellTotalHeights: [50, 100, 50, 100, 50]
cellTotalHeights: [50, 100, 50, 100, 50],
collapsedInputCells: {},
collapsedOutputCells: {},
});
const cellList = createNotebookCellList(instantiationService);
@ -198,7 +206,9 @@ suite('NotebookCellList', () => {
viewModel.restoreEditorViewState({
editingCells: [false, false, false, false, false],
editorViewStates: [null, null, null, null, null],
cellTotalHeights: [50, 100, 50, 100, 50]
cellTotalHeights: [50, 100, 50, 100, 50],
collapsedInputCells: {},
collapsedOutputCells: {},
});
const cellList = createNotebookCellList(instantiationService);
@ -248,7 +258,9 @@ suite('NotebookCellList', () => {
viewModel.restoreEditorViewState({
editingCells: [false, false, false, false, false],
editorViewStates: [null, null, null, null, null],
cellTotalHeights: [50, 100, 50, 100, 50]
cellTotalHeights: [50, 100, 50, 100, 50],
collapsedInputCells: {},
collapsedOutputCells: {},
});
const cellList = createNotebookCellList(instantiationService);
@ -281,7 +293,9 @@ suite('NotebookCellList', () => {
viewModel.restoreEditorViewState({
editingCells: [false, false, false, false, false],
editorViewStates: [null, null, null, null, null],
cellTotalHeights: [50, 100, 50, 100, 50]
cellTotalHeights: [50, 100, 50, 100, 50],
collapsedInputCells: {},
collapsedOutputCells: {},
});
const cellList = createNotebookCellList(instantiationService);