From ab04541f580b9c8564d98acaace40aa5d4725cbd Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Thu, 27 Aug 2020 14:56:17 -0700 Subject: [PATCH] Don't rerender outputs that were already rendered on metadata update and don't render new outputs when the cell output is collapsed Fix #104580 --- .../notebook/browser/notebookEditorWidget.ts | 46 +++++++++---------- .../browser/view/renderers/codeCell.ts | 15 ++++-- 2 files changed, 33 insertions(+), 28 deletions(-) diff --git a/src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts b/src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts index df7797413d7..f12b346c3e6 100644 --- a/src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts +++ b/src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts @@ -6,11 +6,16 @@ import { getZoomLevel } from 'vs/base/browser/browser'; import * as DOM from 'vs/base/browser/dom'; import { IMouseWheelEvent, StandardMouseEvent } from 'vs/base/browser/mouseEvent'; +import { IListContextMenuEvent } from 'vs/base/browser/ui/list/list'; +import { IAction, Separator } from 'vs/base/common/actions'; import { CancellationTokenSource } from 'vs/base/common/cancellation'; import { Color, RGBA } from 'vs/base/common/color'; import { onUnexpectedError } from 'vs/base/common/errors'; import { Emitter, Event } from 'vs/base/common/event'; -import { combinedDisposable, DisposableStore, Disposable, IDisposable, toDisposable } from 'vs/base/common/lifecycle'; +import { combinedDisposable, Disposable, DisposableStore, IDisposable, toDisposable } from 'vs/base/common/lifecycle'; +import { ScrollEvent } from 'vs/base/common/scrollable'; +import { URI } from 'vs/base/common/uri'; +import { generateUuid } from 'vs/base/common/uuid'; import 'vs/css!./media/notebook'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { IEditorOptions } from 'vs/editor/common/config/editorOptions'; @@ -18,45 +23,40 @@ import { BareFontInfo } from 'vs/editor/common/config/fontInfo'; import { Range } from 'vs/editor/common/core/range'; import { IEditor } from 'vs/editor/common/editorCommon'; import * as nls from 'vs/nls'; +import { IMenuService, MenuId } from 'vs/platform/actions/common/actions'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; +import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; +import { ILayoutService } from 'vs/platform/layout/browser/layoutService'; import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; -import { contrastBorder, editorBackground, focusBorder, foreground, registerColor, textBlockQuoteBackground, textBlockQuoteBorder, textLinkActiveForeground, textLinkForeground, textPreformatForeground, errorForeground, transparent, listFocusBackground, listInactiveSelectionBackground, scrollbarSliderBackground, scrollbarSliderHoverBackground, scrollbarSliderActiveBackground, diffRemoved, diffInserted } from 'vs/platform/theme/common/colorRegistry'; +import { contrastBorder, diffInserted, diffRemoved, editorBackground, errorForeground, focusBorder, foreground, listFocusBackground, listInactiveSelectionBackground, registerColor, scrollbarSliderActiveBackground, scrollbarSliderBackground, scrollbarSliderHoverBackground, textBlockQuoteBackground, textBlockQuoteBorder, textLinkActiveForeground, textLinkForeground, textPreformatForeground, transparent } from 'vs/platform/theme/common/colorRegistry'; import { registerThemingParticipant } from 'vs/platform/theme/common/themeService'; import { EditorMemento } from 'vs/workbench/browser/parts/editor/editorPane'; import { IEditorMemento } from 'vs/workbench/common/editor'; -import { CELL_MARGIN, CELL_RUN_GUTTER, CELL_TOP_MARGIN, SCROLLABLE_ELEMENT_PADDING_TOP, BOTTOM_CELL_TOOLBAR_GAP, CELL_BOTTOM_MARGIN, CODE_CELL_LEFT_MARGIN, COLLAPSED_INDICATOR_HEIGHT, BOTTOM_CELL_TOOLBAR_HEIGHT } from 'vs/workbench/contrib/notebook/browser/constants'; -import { CellEditState, CellFocusMode, ICellRange, ICellViewModel, INotebookCellList, INotebookEditor, INotebookEditorContribution, INotebookEditorMouseEvent, NotebookLayoutInfo, NOTEBOOK_EDITOR_EDITABLE, NOTEBOOK_EDITOR_EXECUTING_NOTEBOOK, NOTEBOOK_EDITOR_FOCUSED, NOTEBOOK_EDITOR_RUNNABLE, NOTEBOOK_HAS_MULTIPLE_KERNELS, NOTEBOOK_OUTPUT_FOCUSED, INotebookDeltaDecoration, NotebookEditorOptions, INotebookEditorCreationOptions, INotebookEditorContributionDescription } from 'vs/workbench/contrib/notebook/browser/notebookBrowser'; +import { Memento, MementoObject } from 'vs/workbench/common/memento'; +import { PANEL_BORDER } from 'vs/workbench/common/theme'; +import { debugIconStartForeground } from 'vs/workbench/contrib/debug/browser/debugToolBar'; +import { BOTTOM_CELL_TOOLBAR_GAP, BOTTOM_CELL_TOOLBAR_HEIGHT, CELL_BOTTOM_MARGIN, CELL_MARGIN, CELL_RUN_GUTTER, CELL_TOP_MARGIN, CODE_CELL_LEFT_MARGIN, COLLAPSED_INDICATOR_HEIGHT, SCROLLABLE_ELEMENT_PADDING_TOP } from 'vs/workbench/contrib/notebook/browser/constants'; +import { CellEditState, CellFocusMode, ICellRange, ICellViewModel, INotebookCellList, INotebookDeltaDecoration, INotebookEditor, INotebookEditorContribution, INotebookEditorContributionDescription, INotebookEditorCreationOptions, INotebookEditorMouseEvent, NotebookEditorOptions, NotebookLayoutInfo, NOTEBOOK_EDITOR_EDITABLE, NOTEBOOK_EDITOR_EXECUTING_NOTEBOOK, NOTEBOOK_EDITOR_FOCUSED, NOTEBOOK_EDITOR_RUNNABLE, NOTEBOOK_HAS_MULTIPLE_KERNELS, NOTEBOOK_OUTPUT_FOCUSED } from 'vs/workbench/contrib/notebook/browser/notebookBrowser'; import { NotebookEditorExtensionsRegistry } from 'vs/workbench/contrib/notebook/browser/notebookEditorExtensions'; +import { NotebookKernelProviderAssociations, notebookKernelProviderAssociationsSettingId } from 'vs/workbench/contrib/notebook/browser/notebookKernelAssociation'; import { NotebookCellList } from 'vs/workbench/contrib/notebook/browser/view/notebookCellList'; import { OutputRenderer } from 'vs/workbench/contrib/notebook/browser/view/output/outputRenderer'; import { BackLayerWebView } from 'vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView'; -import { CodeCellRenderer, MarkdownCellRenderer, NotebookCellListDelegate, ListTopCellToolbar } from 'vs/workbench/contrib/notebook/browser/view/renderers/cellRenderer'; +import { CellContextKeyManager } from 'vs/workbench/contrib/notebook/browser/view/renderers/cellContextKeys'; +import { CodeCellRenderer, ListTopCellToolbar, MarkdownCellRenderer, NotebookCellListDelegate } from 'vs/workbench/contrib/notebook/browser/view/renderers/cellRenderer'; +import { CellDragAndDropController } from 'vs/workbench/contrib/notebook/browser/view/renderers/dnd'; import { CodeCellViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/codeCellViewModel'; import { NotebookEventDispatcher, NotebookLayoutChangedEvent } from 'vs/workbench/contrib/notebook/browser/viewModel/eventDispatcher'; import { CellViewModel, IModelDecorationsChangeAccessor, INotebookEditorViewState, NotebookViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/notebookViewModel'; -import { CellKind, IProcessedOutput, INotebookKernelInfo, INotebookKernelInfoDto, INotebookKernelInfo2, NotebookRunState, NotebookCellRunState, IInsetRenderOutput, CellToolbarLocKey, ShowCellStatusbarKey } from 'vs/workbench/contrib/notebook/common/notebookCommon'; +import { NotebookTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookTextModel'; +import { CellKind, CellToolbarLocKey, IInsetRenderOutput, INotebookKernelInfo, INotebookKernelInfo2, INotebookKernelInfoDto, IProcessedOutput, NotebookCellRunState, NotebookRunState, ShowCellStatusbarKey } from 'vs/workbench/contrib/notebook/common/notebookCommon'; +import { NotebookProviderInfo } from 'vs/workbench/contrib/notebook/common/notebookProvider'; import { INotebookService } from 'vs/workbench/contrib/notebook/common/notebookService'; +import { editorGutterModifiedBackground } from 'vs/workbench/contrib/scm/browser/dirtydiffDecorator'; import { Webview } from 'vs/workbench/contrib/webview/browser/webview'; import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; -import { ILayoutService } from 'vs/platform/layout/browser/layoutService'; -import { generateUuid } from 'vs/base/common/uuid'; -import { Memento, MementoObject } from 'vs/workbench/common/memento'; -import { NotebookTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookTextModel'; -import { URI } from 'vs/base/common/uri'; -import { PANEL_BORDER } from 'vs/workbench/common/theme'; -import { debugIconStartForeground } from 'vs/workbench/contrib/debug/browser/debugToolBar'; -import { CellContextKeyManager } from 'vs/workbench/contrib/notebook/browser/view/renderers/cellContextKeys'; -import { NotebookProviderInfo } from 'vs/workbench/contrib/notebook/common/notebookProvider'; -import { notebookKernelProviderAssociationsSettingId, NotebookKernelProviderAssociations } from 'vs/workbench/contrib/notebook/browser/notebookKernelAssociation'; -import { ScrollEvent } from 'vs/base/common/scrollable'; -import { editorGutterModifiedBackground } from 'vs/workbench/contrib/scm/browser/dirtydiffDecorator'; -import { IListContextMenuEvent } from 'vs/base/browser/ui/list/list'; -import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; -import { IMenuService, MenuId } from 'vs/platform/actions/common/actions'; -import { IAction, Separator } from 'vs/base/common/actions'; -import { CellDragAndDropController } from 'vs/workbench/contrib/notebook/browser/view/renderers/dnd'; const $ = DOM.$; diff --git a/src/vs/workbench/contrib/notebook/browser/view/renderers/codeCell.ts b/src/vs/workbench/contrib/notebook/browser/view/renderers/codeCell.ts index 524f3326aaf..9ed49e93300 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/renderers/codeCell.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/renderers/codeCell.ts @@ -17,7 +17,7 @@ import { EDITOR_BOTTOM_PADDING, EDITOR_TOP_PADDING } from 'vs/workbench/contrib/ import { CellFocusMode, CodeCellRenderTemplate, INotebookEditor } from 'vs/workbench/contrib/notebook/browser/notebookBrowser'; import { getResizesObserver } from 'vs/workbench/contrib/notebook/browser/view/renderers/sizeObserver'; import { CodeCellViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/codeCellViewModel'; -import { BUILTIN_RENDERER_ID, CellOutputKind, IProcessedOutput, IRenderOutput, ITransformedDisplayOutputDto, outputHasDynamicHeight, RenderOutputType } from 'vs/workbench/contrib/notebook/common/notebookCommon'; +import { BUILTIN_RENDERER_ID, CellOutputKind, IInsetRenderOutput, IProcessedOutput, IRenderOutput, ITransformedDisplayOutputDto, outputHasDynamicHeight, RenderOutputType } from 'vs/workbench/contrib/notebook/common/notebookCommon'; import { INotebookService } from 'vs/workbench/contrib/notebook/common/notebookService'; interface IMimeTypeRenderer extends IQuickPickItem { @@ -196,7 +196,7 @@ export class CodeCell extends Disposable { // newly added element const currIndex = this.viewCell.outputs.indexOf(output); this.renderOutput(output, currIndex, prevElement); - prevElement = this.outputElements.get(output)!.element; + prevElement = this.outputElements.get(output)?.element; }); const editorHeight = templateData.editor!.getContentHeight(); @@ -326,13 +326,14 @@ export class CodeCell extends Disposable { const renderedOutput = this.outputElements.get(currOutput); if (renderedOutput) { if (renderedOutput.renderResult.type !== RenderOutputType.None) { - // Show inset in webview, or render output that isn't rendered - // TODO@roblou skipHeightInit flag is a hack - the webview only sends the real height once. Don't wipe it out here. - this.renderOutput(currOutput, index, undefined); + this.modifyInsetQueue = this.modifyInsetQueue.finally(() => this.notebookEditor.createInset(this.viewCell, renderedOutput.renderResult as IInsetRenderOutput, this.viewCell.getOutputOffset(index))); } else { // Anything else, just update the height this.viewCell.updateOutputHeight(index, renderedOutput.element.clientHeight); } + } else { + // Wasn't previously rendered, render it now + this.renderOutput(currOutput, index); } } @@ -438,6 +439,10 @@ export class CodeCell extends Disposable { } private renderOutput(currOutput: IProcessedOutput, index: number, beforeElement?: HTMLElement) { + if (this.viewCell.metadata.outputCollapsed) { + return; + } + if (!this.outputResizeListeners.has(currOutput)) { this.outputResizeListeners.set(currOutput, new DisposableStore()); }