notebookBrowser.ts 17.2 KB
Newer Older
R
rebornix 已提交
1 2 3 4 5 6
/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/

import { IMouseWheelEvent } from 'vs/base/browser/mouseEvent';
R
rebornix 已提交
7 8
import { IListEvent, IListMouseEvent } from 'vs/base/browser/ui/list/list';
import { IListOptions, IListStyles } from 'vs/base/browser/ui/list/listWidget';
9
import { ProgressBar } from 'vs/base/browser/ui/progressbar/progressbar';
10
import { ToolBar } from 'vs/base/browser/ui/toolbar/toolbar';
11
import { CancellationTokenSource } from 'vs/base/common/cancellation';
R
rebornix 已提交
12 13 14
import { Event } from 'vs/base/common/event';
import { DisposableStore, IDisposable } from 'vs/base/common/lifecycle';
import { ScrollEvent } from 'vs/base/common/scrollable';
R
rebornix 已提交
15
import { URI } from 'vs/base/common/uri';
R
Rob Lourens 已提交
16
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
17
import { BareFontInfo } from 'vs/editor/common/config/fontInfo';
K
kieferrm 已提交
18
import { IPosition } from 'vs/editor/common/core/position';
19
import { Range } from 'vs/editor/common/core/range';
20
import { FindMatch, IReadonlyTextBuffer, ITextModel } from 'vs/editor/common/model';
21
import { ContextKeyExpr, RawContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
22
import { OutputRenderer } from 'vs/workbench/contrib/notebook/browser/view/output/outputRenderer';
23
import { CellLanguageStatusBarItem, TimerRenderer } from 'vs/workbench/contrib/notebook/browser/view/renderers/cellRenderer';
24
import { CellViewModel, IModelDecorationsChangeAccessor, NotebookViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/notebookViewModel';
R
rebornix 已提交
25
import { NotebookCellTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookCellTextModel';
R
rebornix 已提交
26
import { CellKind, IOutput, IRenderOutput, NotebookCellMetadata, NotebookDocumentMetadata, INotebookKernelInfo } from 'vs/workbench/contrib/notebook/common/notebookCommon';
R
rebornix 已提交
27
import { Webview } from 'vs/workbench/contrib/webview/browser/webview';
28
import { ICompositeCodeEditor } from 'vs/editor/common/editorCommon';
R
rebornix 已提交
29 30

export const KEYBINDING_CONTEXT_NOTEBOOK_FIND_WIDGET_FOCUSED = new RawContextKey<boolean>('notebookFindWidgetFocused', false);
R
rebornix 已提交
31

32 33 34
// Is Notebook
export const NOTEBOOK_IS_ACTIVE_EDITOR = ContextKeyExpr.equals('activeEditor', 'workbench.editor.notebook');

35
// Editor keys
36
export const NOTEBOOK_EDITOR_FOCUSED = new RawContextKey<boolean>('notebookEditorFocused', false);
37 38 39
export const NOTEBOOK_EDITOR_EDITABLE = new RawContextKey<boolean>('notebookEditable', true);
export const NOTEBOOK_EDITOR_RUNNABLE = new RawContextKey<boolean>('notebookRunnable', true);
export const NOTEBOOK_EDITOR_EXECUTING_NOTEBOOK = new RawContextKey<boolean>('notebookExecuting', false);
40

41 42 43 44 45 46 47
// Cell keys
export const NOTEBOOK_VIEW_TYPE = new RawContextKey<string>('notebookViewType', undefined);
export const NOTEBOOK_CELL_TYPE = new RawContextKey<string>('notebookCellType', undefined); // code, markdown
export const NOTEBOOK_CELL_EDITABLE = new RawContextKey<boolean>('notebookCellEditable', false); // bool
export const NOTEBOOK_CELL_RUNNABLE = new RawContextKey<boolean>('notebookCellRunnable', false); // bool
export const NOTEBOOK_CELL_MARKDOWN_EDIT_MODE = new RawContextKey<boolean>('notebookCellMarkdownEditMode', false); // bool
export const NOTEBOOK_CELL_RUN_STATE = new RawContextKey<string>('notebookCellRunState', undefined); // idle, running
R
rebornix 已提交
48
export const NOTEBOOK_CELL_HAS_OUTPUTS = new RawContextKey<boolean>('notebookCellHasOutputs', false); // bool
49

R
rebornix 已提交
50 51 52 53
// Kernels

export const NOTEBOOK_HAS_MULTIPLE_KERNELS = new RawContextKey<boolean>('notebookHasMultipleKernels', false);

R
rebornix 已提交
54 55 56 57 58 59
export interface NotebookLayoutInfo {
	width: number;
	height: number;
	fontInfo: BareFontInfo;
}

R
rebornix 已提交
60 61 62 63 64 65 66 67 68 69 70
export interface NotebookLayoutChangeEvent {
	width?: boolean;
	height?: boolean;
	fontInfo?: boolean;
}

export interface CodeCellLayoutInfo {
	readonly fontInfo: BareFontInfo | null;
	readonly editorHeight: number;
	readonly editorWidth: number;
	readonly totalHeight: number;
71
	readonly outputContainerOffset: number;
R
rebornix 已提交
72 73
	readonly outputTotalHeight: number;
	readonly indicatorHeight: number;
R
rebornix 已提交
74
	readonly bottomToolbarOffset: number;
R
rebornix 已提交
75 76 77 78 79 80
}

export interface CodeCellLayoutChangeEvent {
	editorHeight?: boolean;
	outputHeight?: boolean;
	totalHeight?: boolean;
R
rebornix 已提交
81 82
	outerWidth?: number;
	font?: BareFontInfo;
R
rebornix 已提交
83 84 85 86 87
}

export interface MarkdownCellLayoutInfo {
	readonly fontInfo: BareFontInfo | null;
	readonly editorWidth: number;
R
Rob Lourens 已提交
88
	readonly editorHeight: number;
R
rebornix 已提交
89
	readonly bottomToolbarOffset: number;
R
rebornix 已提交
90
	readonly totalHeight: number;
R
rebornix 已提交
91 92 93
}

export interface MarkdownCellLayoutChangeEvent {
R
rebornix 已提交
94 95
	font?: BareFontInfo;
	outerWidth?: number;
R
rebornix 已提交
96
	totalHeight?: number;
R
Rob Lourens 已提交
97
	editorHeight?: boolean;
R
rebornix 已提交
98 99
}

R
rebornix 已提交
100
export interface ICellViewModel {
R
rebornix 已提交
101
	readonly model: NotebookCellTextModel;
R
rebornix 已提交
102
	readonly id: string;
103
	readonly textBuffer: IReadonlyTextBuffer;
104
	dragging: boolean;
R
rebornix 已提交
105 106
	handle: number;
	uri: URI;
107
	language: string;
R
rebornix 已提交
108
	cellKind: CellKind;
109
	editState: CellEditState;
110 111
	readonly runState: CellRunState;
	currentTokenSource: CancellationTokenSource | undefined;
R
rebornix 已提交
112 113
	focusMode: CellFocusMode;
	getText(): string;
114
	metadata: NotebookCellMetadata | undefined;
115 116 117
	textModel: ITextModel | undefined;
	hasModel(): this is IEditableCellViewModel;
	resolveTextModel(): Promise<ITextModel>;
R
rebornix 已提交
118
	getEvaluatedMetadata(documentMetadata: NotebookDocumentMetadata | undefined): NotebookCellMetadata;
K
kieferrm 已提交
119
	getSelectionsStartPosition(): IPosition[] | undefined;
R
rebornix 已提交
120 121
}

122 123 124 125
export interface IEditableCellViewModel extends ICellViewModel {
	textModel: ITextModel;
}

R
rebornix 已提交
126 127 128 129 130
export interface INotebookEditorMouseEvent {
	readonly event: MouseEvent;
	readonly target: CellViewModel;
}

R
rebornix 已提交
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
export interface INotebookEditorContribution {
	/**
	 * Dispose this contribution.
	 */
	dispose(): void;
	/**
	 * Store view state.
	 */
	saveViewState?(): any;
	/**
	 * Restore view state.
	 */
	restoreViewState?(state: any): void;
}

146
export interface INotebookEditor extends ICompositeCodeEditor {
R
rebornix 已提交
147 148 149 150

	/**
	 * Notebook view model attached to the current editor
	 */
R
rebornix 已提交
151
	viewModel: NotebookViewModel | undefined;
R
rebornix 已提交
152

R
rebornix 已提交
153 154 155 156 157
	/**
	 * An event emitted when the model of this editor has changed.
	 * @event
	 */
	readonly onDidChangeModel: Event<void>;
158
	isNotebookEditor: boolean;
R
rebornix 已提交
159 160
	activeKernel: INotebookKernelInfo | undefined;
	readonly onDidChangeKernel: Event<void>;
161

R
rebornix 已提交
162
	getDomNode(): HTMLElement;
R
rebornix 已提交
163 164
	getInnerWebview(): Webview | undefined;

R
rebornix 已提交
165 166 167
	/**
	 * Focus the notebook editor cell list
	 */
R
rebornix 已提交
168
	focus(): void;
R
rebornix 已提交
169

R
rebornix 已提交
170 171 172
	/**
	 * Select & focus cell
	 */
R
rebornix 已提交
173
	selectElement(cell: ICellViewModel): void;
R
rebornix 已提交
174

R
rebornix 已提交
175 176 177
	/**
	 * Layout info for the notebook editor
	 */
R
rebornix 已提交
178
	getLayoutInfo(): NotebookLayoutInfo;
R
rebornix 已提交
179 180 181
	/**
	 * Fetch the output renderers for notebook outputs.
	 */
R
rebornix 已提交
182
	getOutputRenderer(): OutputRenderer;
R
rebornix 已提交
183 184 185 186

	/**
	 * Insert a new cell around `cell`
	 */
R
rebornix 已提交
187
	insertNotebookCell(cell: ICellViewModel | undefined, type: CellKind, direction?: 'above' | 'below', initialText?: string, ui?: boolean): CellViewModel | null;
R
rebornix 已提交
188

K
kieferrm 已提交
189 190 191
	/**
	 * Split a given cell into multiple cells of the same type using the selection start positions.
	 */
192
	splitNotebookCell(cell: ICellViewModel): Promise<CellViewModel[] | null>;
K
kieferrm 已提交
193 194 195 196 197 198

	/**
	 * Joins the given cell either with the cell above or the one below depending on the given direction.
	 */
	joinNotebookCells(cell: ICellViewModel, direction: 'above' | 'below', constraint?: CellKind): Promise<ICellViewModel | null>;

R
rebornix 已提交
199 200 201
	/**
	 * Delete a cell from the notebook
	 */
202
	deleteNotebookCell(cell: ICellViewModel): Promise<boolean>;
R
rebornix 已提交
203

204 205 206
	/**
	 * Move a cell up one spot
	 */
207
	moveCellUp(cell: ICellViewModel): Promise<boolean>;
208 209 210 211

	/**
	 * Move a cell down one spot
	 */
212
	moveCellDown(cell: ICellViewModel): Promise<boolean>;
213

R
Rob Lourens 已提交
214 215 216
	/**
	 * Move a cell above or below another cell
	 */
217
	moveCell(cell: ICellViewModel, relativeToCell: ICellViewModel, direction: 'above' | 'below'): Promise<boolean>;
R
Rob Lourens 已提交
218

R
rebornix 已提交
219 220 221 222 223 224
	/**
	 * Switch the cell into editing mode.
	 *
	 * For code cell, the monaco editor will be focused.
	 * For markdown cell, it will switch from preview mode to editing mode, which focuses the monaco editor.
	 */
R
rebornix 已提交
225
	editNotebookCell(cell: ICellViewModel): void;
R
rebornix 已提交
226 227 228 229

	/**
	 * Quit cell editing mode.
	 */
R
rebornix 已提交
230
	saveNotebookCell(cell: ICellViewModel): void;
R
rebornix 已提交
231 232 233 234

	/**
	 * Focus the container of a cell (the monaco editor inside is not focused).
	 */
C
Christopher Maynard 已提交
235
	focusNotebookCell(cell: ICellViewModel, focus: 'editor' | 'container' | 'output'): void;
R
rebornix 已提交
236

237 238 239 240 241
	/**
	 * Execute the given notebook cell
	 */
	executeNotebookCell(cell: ICellViewModel): Promise<void>;

242 243 244 245 246 247 248 249 250 251 252 253 254 255 256
	/**
	 * Cancel the cell execution
	 */
	cancelNotebookCellExecution(cell: ICellViewModel): void;

	/**
	 * Executes all notebook cells in order
	 */
	executeNotebook(): Promise<void>;

	/**
	 * Cancel the notebook execution
	 */
	cancelNotebookExecution(): void;

R
rebornix 已提交
257 258 259
	/**
	 * Get current active cell
	 */
R
rebornix 已提交
260
	getActiveCell(): ICellViewModel | undefined;
R
rebornix 已提交
261 262 263 264

	/**
	 * Layout the cell with a new height
	 */
265
	layoutNotebookCell(cell: ICellViewModel, height: number): Promise<void>;
R
rebornix 已提交
266 267 268 269

	/**
	 * Render the output in webview layer
	 */
R
rebornix 已提交
270
	createInset(cell: ICellViewModel, output: IOutput, shadowContent: string, offset: number): void;
R
rebornix 已提交
271 272 273 274

	/**
	 * Remove the output from the webview layer
	 */
R
rebornix 已提交
275
	removeInset(output: IOutput): void;
R
rebornix 已提交
276

277 278 279 280 281
	/**
	 * Send message to the webview for outputs.
	 */
	postMessage(message: any): void;

R
rebornix 已提交
282 283 284
	/**
	 * Trigger the editor to scroll from scroll event programmatically
	 */
285
	triggerScroll(event: IMouseWheelEvent): void;
R
rebornix 已提交
286 287 288 289

	/**
	 * Reveal cell into viewport.
	 */
R
rebornix 已提交
290
	revealInView(cell: ICellViewModel): void;
R
rebornix 已提交
291 292 293 294

	/**
	 * Reveal cell into viewport center.
	 */
R
rebornix 已提交
295
	revealInCenter(cell: ICellViewModel): void;
R
rebornix 已提交
296 297 298 299

	/**
	 * Reveal cell into viewport center if cell is currently out of the viewport.
	 */
R
rebornix 已提交
300
	revealInCenterIfOutsideViewport(cell: ICellViewModel): void;
R
rebornix 已提交
301 302 303 304

	/**
	 * Reveal a line in notebook cell into viewport with minimal scrolling.
	 */
R
rebornix 已提交
305
	revealLineInView(cell: ICellViewModel, line: number): void;
R
rebornix 已提交
306

R
rebornix 已提交
307 308 309
	/**
	 * Reveal a line in notebook cell into viewport center.
	 */
R
rebornix 已提交
310
	revealLineInCenter(cell: ICellViewModel, line: number): void;
R
rebornix 已提交
311 312 313 314

	/**
	 * Reveal a line in notebook cell into viewport center.
	 */
R
rebornix 已提交
315
	revealLineInCenterIfOutsideViewport(cell: ICellViewModel, line: number): void;
R
rebornix 已提交
316

R
rebornix 已提交
317 318 319
	/**
	 * Reveal a range in notebook cell into viewport with minimal scrolling.
	 */
R
rebornix 已提交
320
	revealRangeInView(cell: ICellViewModel, range: Range): void;
R
rebornix 已提交
321 322 323 324

	/**
	 * Reveal a range in notebook cell into viewport center.
	 */
R
rebornix 已提交
325
	revealRangeInCenter(cell: ICellViewModel, range: Range): void;
R
rebornix 已提交
326 327 328 329

	/**
	 * Reveal a range in notebook cell into viewport center.
	 */
R
rebornix 已提交
330
	revealRangeInCenterIfOutsideViewport(cell: ICellViewModel, range: Range): void;
R
rebornix 已提交
331

R
rebornix 已提交
332 333 334 335 336
	/**
	 * Set hidden areas on cell text models.
	 */
	setHiddenAreas(_ranges: ICellRange[]): boolean;

R
rebornix 已提交
337
	setCellSelection(cell: ICellViewModel, selection: Range): void;
R
rebornix 已提交
338

R
rebornix 已提交
339 340 341 342
	/**
	 * Change the decorations on cells.
	 * The notebook is virtualized and this method should be called to create/delete editor decorations safely.
	 */
R
rebornix 已提交
343
	changeDecorations(callback: (changeAccessor: IModelDecorationsChangeAccessor) => any): any;
R
rebornix 已提交
344

R
rebornix 已提交
345 346 347 348 349 350 351 352 353 354 355
	/**
	 * An event emitted on a "mouseup".
	 * @event
	 */
	onMouseUp(listener: (e: INotebookEditorMouseEvent) => void): IDisposable;

	/**
	 * An event emitted on a "mousedown".
	 * @event
	 */
	onMouseDown(listener: (e: INotebookEditorMouseEvent) => void): IDisposable;
R
rebornix 已提交
356 357 358 359 360 361 362

	/**
	 * Get a contribution of this editor.
	 * @id Unique identifier of the contribution.
	 * @return The contribution or null if contribution not found.
	 */
	getContribution<T extends INotebookEditorContribution>(id: string): T;
R
rebornix 已提交
363 364
}

R
rebornix 已提交
365
export interface INotebookCellList {
366
	readonly contextKeyService: IContextKeyService;
R
Rob Lourens 已提交
367
	elementAt(position: number): ICellViewModel | undefined;
368
	elementHeight(element: ICellViewModel): number;
R
rebornix 已提交
369 370 371 372 373 374 375 376 377
	onWillScroll: Event<ScrollEvent>;
	onDidChangeFocus: Event<IListEvent<ICellViewModel>>;
	onDidChangeContentHeight: Event<number>;
	scrollTop: number;
	scrollHeight: number;
	scrollLeft: number;
	length: number;
	rowsContainer: HTMLElement;
	readonly onDidRemoveOutput: Event<IOutput>;
378
	readonly onDidHideOutput: Event<IOutput>;
R
rebornix 已提交
379 380
	readonly onMouseUp: Event<IListMouseEvent<CellViewModel>>;
	readonly onMouseDown: Event<IListMouseEvent<CellViewModel>>;
R
rebornix 已提交
381 382 383
	detachViewModel(): void;
	attachViewModel(viewModel: NotebookViewModel): void;
	clear(): void;
384
	getViewIndex(cell: ICellViewModel): number | undefined;
R
rebornix 已提交
385 386 387 388 389 390 391 392 393 394 395 396
	focusElement(element: ICellViewModel): void;
	selectElement(element: ICellViewModel): void;
	getFocusedElements(): ICellViewModel[];
	revealElementInView(element: ICellViewModel): void;
	revealElementInCenterIfOutsideViewport(element: ICellViewModel): void;
	revealElementInCenter(element: ICellViewModel): void;
	revealElementLineInView(element: ICellViewModel, line: number): void;
	revealElementLineInCenter(element: ICellViewModel, line: number): void;
	revealElementLineInCenterIfOutsideViewport(element: ICellViewModel, line: number): void;
	revealElementRangeInView(element: ICellViewModel, range: Range): void;
	revealElementRangeInCenter(element: ICellViewModel, range: Range): void;
	revealElementRangeInCenterIfOutsideViewport(element: ICellViewModel, range: Range): void;
R
rebornix 已提交
397
	setHiddenAreas(_ranges: ICellRange[], triggerViewUpdate: boolean): boolean;
R
rebornix 已提交
398 399 400 401 402 403 404 405 406 407 408
	domElementOfElement(element: ICellViewModel): HTMLElement | null;
	focusView(): void;
	getAbsoluteTopOfElement(element: ICellViewModel): number;
	triggerScrollFromMouseWheelEvent(browserEvent: IMouseWheelEvent): void;
	updateElementHeight2(element: ICellViewModel, size: number): void;
	domFocus(): void;
	setCellSelection(element: ICellViewModel, range: Range): void;
	style(styles: IListStyles): void;
	updateOptions(options: IListOptions<ICellViewModel>): void;
	layout(height?: number, width?: number): void;
	dispose(): void;
409 410 411 412 413

	// TODO resolve differences between List<CellViewModel> and INotebookCellList<ICellViewModel>
	getFocus(): number[];
	setFocus(indexes: number[]): void;
	setSelection(indexes: number[]): void;
R
rebornix 已提交
414 415
}

416
export interface BaseCellRenderTemplate {
417
	contextKeyService: IContextKeyService;
R
rebornix 已提交
418 419
	container: HTMLElement;
	cellContainer: HTMLElement;
420
	toolbar: ToolBar;
421
	focusIndicator: HTMLElement;
422
	disposables: DisposableStore;
423
	elementDisposables: DisposableStore;
R
rebornix 已提交
424
	bottomCellContainer: HTMLElement;
R
Rob Lourens 已提交
425
	currentRenderedCell?: ICellViewModel;
426 427
	statusBarContainer: HTMLElement;
	languageStatusBarItem: CellLanguageStatusBarItem;
R
rebornix 已提交
428
	toJSON: () => any;
429 430 431
}

export interface MarkdownCellRenderTemplate extends BaseCellRenderTemplate {
432 433
	editorPart: HTMLElement;
	editorContainer: HTMLElement;
R
rebornix 已提交
434
	foldingIndicator: HTMLElement;
R
Rob Lourens 已提交
435
	currentEditor?: ICodeEditor;
436 437 438
}

export interface CodeCellRenderTemplate extends BaseCellRenderTemplate {
R
Rob Lourens 已提交
439 440
	cellRunStatusContainer: HTMLElement;
	cellStatusMessageContainer: HTMLElement;
441 442 443 444
	runToolbar: ToolBar;
	runButtonContainer: HTMLElement;
	executionOrderLabel: HTMLElement;
	outputContainer: HTMLElement;
R
Rob Lourens 已提交
445
	editor: ICodeEditor;
446
	progressBar: ProgressBar;
447
	timer: TimerRenderer;
R
rebornix 已提交
448
}
R
rebornix 已提交
449 450 451 452 453 454 455 456 457

export interface IOutputTransformContribution {
	/**
	 * Dispose this contribution.
	 */
	dispose(): void;

	render(output: IOutput, container: HTMLElement, preferredMimeType: string | undefined): IRenderOutput;
}
R
rebornix 已提交
458 459 460 461 462 463

export interface CellFindMatch {
	cell: CellViewModel;
	matches: FindMatch[];
}

R
rebornix 已提交
464 465 466 467 468 469 470 471 472
export enum CellRevealType {
	Line,
	Range
}

export enum CellRevealPosition {
	Top,
	Center
}
R
rebornix 已提交
473

474 475 476 477 478 479
export enum CellRunState {
	Idle,
	Running
}

export enum CellEditState {
R
rebornix 已提交
480 481 482 483 484
	/**
	 * Default state.
	 * For markdown cell, it's Markdown preview.
	 * For code cell, the browser focus should be on the container instead of the editor
	 */
485
	Preview,
R
rebornix 已提交
486 487 488 489 490 491 492


	/**
	 * Eding mode. Source for markdown or code is rendered in editors and the state will be persistent.
	 */
	Editing
}
R
rebornix 已提交
493 494 495 496 497 498 499 500 501 502 503 504

export enum CellFocusMode {
	Container,
	Editor
}

export enum CursorAtBoundary {
	None,
	Top,
	Bottom,
	Both
}
R
rebornix 已提交
505

506 507 508 509 510 511 512
export interface CellViewModelStateChangeEvent {
	metadataChanged?: boolean;
	selectionChanged?: boolean;
	focusModeChanged?: boolean;
	runStateChanged?: boolean;
	editStateChanged?: boolean;
	languageChanged?: boolean;
R
rebornix 已提交
513 514
	foldingStateChanged?: boolean;
	contentChanged?: boolean;
515
	outputIsHoveredChanged?: boolean;
516 517
}

R
rebornix 已提交
518
/**
R
rebornix 已提交
519
 * [start, end]
R
rebornix 已提交
520 521
 */
export interface ICellRange {
R
rebornix 已提交
522 523 524
	/**
	 * zero based index
	 */
R
rebornix 已提交
525
	start: number;
R
rebornix 已提交
526

R
rebornix 已提交
527
	/**
R
rebornix 已提交
528
	 * zero based index
R
rebornix 已提交
529
	 */
R
rebornix 已提交
530
	end: number;
R
rebornix 已提交
531 532 533 534 535 536 537 538 539 540 541 542 543 544
}


/**
 * @param _ranges
 */
export function reduceCellRanges(_ranges: ICellRange[]): ICellRange[] {
	if (!_ranges.length) {
		return [];
	}

	let ranges = _ranges.sort((a, b) => a.start - b.start);
	let result: ICellRange[] = [];
	let currentRangeStart = ranges[0].start;
R
rebornix 已提交
545
	let currentRangeEnd = ranges[0].end + 1;
R
rebornix 已提交
546 547 548 549 550

	for (let i = 0, len = ranges.length; i < len; i++) {
		let range = ranges[i];

		if (range.start > currentRangeEnd) {
R
rebornix 已提交
551
			result.push({ start: currentRangeStart, end: currentRangeEnd - 1 });
R
rebornix 已提交
552
			currentRangeStart = range.start;
R
rebornix 已提交
553 554 555
			currentRangeEnd = range.end + 1;
		} else if (range.end + 1 > currentRangeEnd) {
			currentRangeEnd = range.end + 1;
R
rebornix 已提交
556 557 558
		}
	}

R
rebornix 已提交
559
	result.push({ start: currentRangeStart, end: currentRangeEnd - 1 });
R
rebornix 已提交
560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576
	return result;
}

export function getVisibleCells(cells: CellViewModel[], hiddenRanges: ICellRange[]) {
	if (!hiddenRanges.length) {
		return cells;
	}

	let start = 0;
	let hiddenRangeIndex = 0;
	let result: any[] = [];

	while (start < cells.length && hiddenRangeIndex < hiddenRanges.length) {
		if (start < hiddenRanges[hiddenRangeIndex].start) {
			result.push(...cells.slice(start, hiddenRanges[hiddenRangeIndex].start));
		}

R
rebornix 已提交
577
		start = hiddenRanges[hiddenRangeIndex].end + 1;
R
rebornix 已提交
578 579 580 581 582 583 584 585 586
		hiddenRangeIndex++;
	}

	if (start < cells.length) {
		result.push(...cells.slice(start));
	}

	return result;
}