Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/workbench/contrib/notebook/test/browser/notebookViewZones.test.ts
3296 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
7
import assert from 'assert';
8
import { DisposableStore } from '../../../../../base/common/lifecycle.js';
9
import { ensureNoDisposablesAreLeakedInTestSuite } from '../../../../../base/test/common/utils.js';
10
import { IConfigurationService } from '../../../../../platform/configuration/common/configuration.js';
11
import { TestConfigurationService } from '../../../../../platform/configuration/test/common/testConfigurationService.js';
12
import { TestInstantiationService } from '../../../../../platform/instantiation/test/common/instantiationServiceMock.js';
13
import { NotebookCellsLayout } from '../../browser/view/notebookCellListView.js';
14
import { FoldingModel } from '../../browser/viewModel/foldingModel.js';
15
import { CellEditType, CellKind } from '../../common/notebookCommon.js';
16
import { createNotebookCellList, setupInstantiationService, withTestNotebook } from './testNotebookEditor.js';
17
18
suite('NotebookRangeMap', () => {
19
20
ensureNoDisposablesAreLeakedInTestSuite();
21
22
test('empty', () => {
23
const rangeMap = new NotebookCellsLayout();
24
assert.strictEqual(rangeMap.size, 0);
25
assert.strictEqual(rangeMap.count, 0);
26
});
27
28
const one = { size: 1 };
29
const two = { size: 2 };
30
const three = { size: 3 };
31
const five = { size: 5 };
32
const ten = { size: 10 };
33
34
test('length & count', () => {
35
const rangeMap = new NotebookCellsLayout();
36
rangeMap.splice(0, 0, [one]);
37
assert.strictEqual(rangeMap.size, 1);
38
assert.strictEqual(rangeMap.count, 1);
39
});
40
41
test('length & count #2', () => {
42
const rangeMap = new NotebookCellsLayout();
43
rangeMap.splice(0, 0, [one, one, one, one, one]);
44
assert.strictEqual(rangeMap.size, 5);
45
assert.strictEqual(rangeMap.count, 5);
46
});
47
48
test('length & count #3', () => {
49
const rangeMap = new NotebookCellsLayout();
50
rangeMap.splice(0, 0, [five]);
51
assert.strictEqual(rangeMap.size, 5);
52
assert.strictEqual(rangeMap.count, 1);
53
});
54
55
test('length & count #4', () => {
56
const rangeMap = new NotebookCellsLayout();
57
rangeMap.splice(0, 0, [five, five, five, five, five]);
58
assert.strictEqual(rangeMap.size, 25);
59
assert.strictEqual(rangeMap.count, 5);
60
});
61
62
test('insert', () => {
63
const rangeMap = new NotebookCellsLayout();
64
rangeMap.splice(0, 0, [five, five, five, five, five]);
65
assert.strictEqual(rangeMap.size, 25);
66
assert.strictEqual(rangeMap.count, 5);
67
68
rangeMap.splice(0, 0, [five, five, five, five, five]);
69
assert.strictEqual(rangeMap.size, 50);
70
assert.strictEqual(rangeMap.count, 10);
71
72
rangeMap.splice(5, 0, [ten, ten]);
73
assert.strictEqual(rangeMap.size, 70);
74
assert.strictEqual(rangeMap.count, 12);
75
76
rangeMap.splice(12, 0, [{ size: 200 }]);
77
assert.strictEqual(rangeMap.size, 270);
78
assert.strictEqual(rangeMap.count, 13);
79
});
80
81
test('delete', () => {
82
const rangeMap = new NotebookCellsLayout();
83
rangeMap.splice(0, 0, [five, five, five, five, five,
84
five, five, five, five, five,
85
five, five, five, five, five,
86
five, five, five, five, five]);
87
assert.strictEqual(rangeMap.size, 100);
88
assert.strictEqual(rangeMap.count, 20);
89
90
rangeMap.splice(10, 5);
91
assert.strictEqual(rangeMap.size, 75);
92
assert.strictEqual(rangeMap.count, 15);
93
94
rangeMap.splice(0, 1);
95
assert.strictEqual(rangeMap.size, 70);
96
assert.strictEqual(rangeMap.count, 14);
97
98
rangeMap.splice(1, 13);
99
assert.strictEqual(rangeMap.size, 5);
100
assert.strictEqual(rangeMap.count, 1);
101
102
rangeMap.splice(1, 1);
103
assert.strictEqual(rangeMap.size, 5);
104
assert.strictEqual(rangeMap.count, 1);
105
});
106
107
test('insert & delete', () => {
108
const rangeMap = new NotebookCellsLayout();
109
assert.strictEqual(rangeMap.size, 0);
110
assert.strictEqual(rangeMap.count, 0);
111
112
rangeMap.splice(0, 0, [one]);
113
assert.strictEqual(rangeMap.size, 1);
114
assert.strictEqual(rangeMap.count, 1);
115
116
rangeMap.splice(0, 1);
117
assert.strictEqual(rangeMap.size, 0);
118
assert.strictEqual(rangeMap.count, 0);
119
});
120
121
test('insert & delete #2', () => {
122
const rangeMap = new NotebookCellsLayout();
123
rangeMap.splice(0, 0, [one, one, one, one, one,
124
one, one, one, one, one]);
125
rangeMap.splice(2, 6);
126
assert.strictEqual(rangeMap.count, 4);
127
assert.strictEqual(rangeMap.size, 4);
128
});
129
130
test('insert & delete #3', () => {
131
const rangeMap = new NotebookCellsLayout();
132
rangeMap.splice(0, 0, [one, one, one, one, one,
133
one, one, one, one, one,
134
two, two, two, two, two,
135
two, two, two, two, two]);
136
rangeMap.splice(8, 4);
137
assert.strictEqual(rangeMap.count, 16);
138
assert.strictEqual(rangeMap.size, 24);
139
});
140
141
test('insert & delete #4', () => {
142
const rangeMap = new NotebookCellsLayout();
143
rangeMap.splice(0, 0, [one, one, one, one, one,
144
one, one, one, one, one,
145
two, two, two, two, two,
146
two, two, two, two, two]);
147
rangeMap.splice(5, 0, [three, three, three, three, three]);
148
assert.strictEqual(rangeMap.count, 25);
149
assert.strictEqual(rangeMap.size, 45);
150
151
rangeMap.splice(4, 7);
152
assert.strictEqual(rangeMap.count, 18);
153
assert.strictEqual(rangeMap.size, 28);
154
});
155
156
suite('indexAt, positionAt', () => {
157
test('empty', () => {
158
const rangeMap = new NotebookCellsLayout();
159
assert.strictEqual(rangeMap.indexAt(0), 0);
160
assert.strictEqual(rangeMap.indexAt(10), 0);
161
assert.strictEqual(rangeMap.indexAt(-1), -1);
162
assert.strictEqual(rangeMap.positionAt(0), -1);
163
assert.strictEqual(rangeMap.positionAt(10), -1);
164
assert.strictEqual(rangeMap.positionAt(-1), -1);
165
});
166
167
test('simple', () => {
168
const rangeMap = new NotebookCellsLayout();
169
rangeMap.splice(0, 0, [one]);
170
assert.strictEqual(rangeMap.indexAt(0), 0);
171
assert.strictEqual(rangeMap.indexAt(1), 1);
172
assert.strictEqual(rangeMap.positionAt(0), 0);
173
assert.strictEqual(rangeMap.positionAt(1), -1);
174
});
175
176
test('simple #2', () => {
177
const rangeMap = new NotebookCellsLayout();
178
rangeMap.splice(0, 0, [ten]);
179
assert.strictEqual(rangeMap.indexAt(0), 0);
180
assert.strictEqual(rangeMap.indexAt(5), 0);
181
assert.strictEqual(rangeMap.indexAt(9), 0);
182
assert.strictEqual(rangeMap.indexAt(10), 1);
183
assert.strictEqual(rangeMap.positionAt(0), 0);
184
assert.strictEqual(rangeMap.positionAt(1), -1);
185
});
186
187
test('insert', () => {
188
const rangeMap = new NotebookCellsLayout();
189
rangeMap.splice(0, 0, [one, one, one, one, one, one, one, one, one, one]);
190
assert.strictEqual(rangeMap.indexAt(0), 0);
191
assert.strictEqual(rangeMap.indexAt(1), 1);
192
assert.strictEqual(rangeMap.indexAt(5), 5);
193
assert.strictEqual(rangeMap.indexAt(9), 9);
194
assert.strictEqual(rangeMap.indexAt(10), 10);
195
assert.strictEqual(rangeMap.indexAt(11), 10);
196
197
rangeMap.splice(10, 0, [one, one, one, one, one, one, one, one, one, one]);
198
assert.strictEqual(rangeMap.indexAt(10), 10);
199
assert.strictEqual(rangeMap.indexAt(19), 19);
200
assert.strictEqual(rangeMap.indexAt(20), 20);
201
assert.strictEqual(rangeMap.indexAt(21), 20);
202
assert.strictEqual(rangeMap.positionAt(0), 0);
203
assert.strictEqual(rangeMap.positionAt(1), 1);
204
assert.strictEqual(rangeMap.positionAt(19), 19);
205
assert.strictEqual(rangeMap.positionAt(20), -1);
206
});
207
208
test('delete', () => {
209
const rangeMap = new NotebookCellsLayout();
210
rangeMap.splice(0, 0, [one, one, one, one, one, one, one, one, one, one]);
211
rangeMap.splice(2, 6);
212
213
assert.strictEqual(rangeMap.indexAt(0), 0);
214
assert.strictEqual(rangeMap.indexAt(1), 1);
215
assert.strictEqual(rangeMap.indexAt(3), 3);
216
assert.strictEqual(rangeMap.indexAt(4), 4);
217
assert.strictEqual(rangeMap.indexAt(5), 4);
218
assert.strictEqual(rangeMap.positionAt(0), 0);
219
assert.strictEqual(rangeMap.positionAt(1), 1);
220
assert.strictEqual(rangeMap.positionAt(3), 3);
221
assert.strictEqual(rangeMap.positionAt(4), -1);
222
});
223
224
test('delete #2', () => {
225
const rangeMap = new NotebookCellsLayout();
226
rangeMap.splice(0, 0, [ten, ten, ten, ten, ten, ten, ten, ten, ten, ten]);
227
rangeMap.splice(2, 6);
228
229
assert.strictEqual(rangeMap.indexAt(0), 0);
230
assert.strictEqual(rangeMap.indexAt(1), 0);
231
assert.strictEqual(rangeMap.indexAt(30), 3);
232
assert.strictEqual(rangeMap.indexAt(40), 4);
233
assert.strictEqual(rangeMap.indexAt(50), 4);
234
assert.strictEqual(rangeMap.positionAt(0), 0);
235
assert.strictEqual(rangeMap.positionAt(1), 10);
236
assert.strictEqual(rangeMap.positionAt(2), 20);
237
assert.strictEqual(rangeMap.positionAt(3), 30);
238
assert.strictEqual(rangeMap.positionAt(4), -1);
239
});
240
});
241
});
242
243
suite('NotebookRangeMap with top padding', () => {
244
245
ensureNoDisposablesAreLeakedInTestSuite();
246
247
test('empty', () => {
248
const rangeMap = new NotebookCellsLayout(10);
249
assert.strictEqual(rangeMap.size, 10);
250
assert.strictEqual(rangeMap.count, 0);
251
});
252
253
const one = { size: 1 };
254
const five = { size: 5 };
255
const ten = { size: 10 };
256
257
test('length & count', () => {
258
const rangeMap = new NotebookCellsLayout(10);
259
rangeMap.splice(0, 0, [one]);
260
assert.strictEqual(rangeMap.size, 11);
261
assert.strictEqual(rangeMap.count, 1);
262
});
263
264
test('length & count #2', () => {
265
const rangeMap = new NotebookCellsLayout(10);
266
rangeMap.splice(0, 0, [one, one, one, one, one]);
267
assert.strictEqual(rangeMap.size, 15);
268
assert.strictEqual(rangeMap.count, 5);
269
});
270
271
test('length & count #3', () => {
272
const rangeMap = new NotebookCellsLayout(10);
273
rangeMap.splice(0, 0, [five]);
274
assert.strictEqual(rangeMap.size, 15);
275
assert.strictEqual(rangeMap.count, 1);
276
});
277
278
test('length & count #4', () => {
279
const rangeMap = new NotebookCellsLayout(10);
280
rangeMap.splice(0, 0, [five, five, five, five, five]);
281
assert.strictEqual(rangeMap.size, 35);
282
assert.strictEqual(rangeMap.count, 5);
283
});
284
285
test('insert', () => {
286
const rangeMap = new NotebookCellsLayout(10);
287
rangeMap.splice(0, 0, [five, five, five, five, five]);
288
assert.strictEqual(rangeMap.size, 35);
289
assert.strictEqual(rangeMap.count, 5);
290
291
rangeMap.splice(0, 0, [five, five, five, five, five]);
292
assert.strictEqual(rangeMap.size, 60);
293
assert.strictEqual(rangeMap.count, 10);
294
295
rangeMap.splice(5, 0, [ten, ten]);
296
assert.strictEqual(rangeMap.size, 80);
297
assert.strictEqual(rangeMap.count, 12);
298
299
rangeMap.splice(12, 0, [{ size: 200 }]);
300
assert.strictEqual(rangeMap.size, 280);
301
assert.strictEqual(rangeMap.count, 13);
302
});
303
304
suite('indexAt, positionAt', () => {
305
test('empty', () => {
306
const rangeMap = new NotebookCellsLayout(10);
307
assert.strictEqual(rangeMap.indexAt(0), 0);
308
assert.strictEqual(rangeMap.indexAt(10), 0);
309
assert.strictEqual(rangeMap.indexAt(-1), -1);
310
assert.strictEqual(rangeMap.positionAt(0), -1);
311
assert.strictEqual(rangeMap.positionAt(10), -1);
312
assert.strictEqual(rangeMap.positionAt(-1), -1);
313
});
314
315
test('simple', () => {
316
const rangeMap = new NotebookCellsLayout(10);
317
rangeMap.splice(0, 0, [one]);
318
assert.strictEqual(rangeMap.indexAt(0), 0);
319
assert.strictEqual(rangeMap.indexAt(1), 0);
320
assert.strictEqual(rangeMap.indexAt(10), 0);
321
assert.strictEqual(rangeMap.indexAt(11), 1);
322
assert.strictEqual(rangeMap.positionAt(0), 10);
323
assert.strictEqual(rangeMap.positionAt(1), -1);
324
});
325
});
326
});
327
328
suite('NotebookRangeMap with whitesspaces', () => {
329
let testDisposables: DisposableStore;
330
let instantiationService: TestInstantiationService;
331
let config: TestConfigurationService;
332
333
teardown(() => {
334
testDisposables.dispose();
335
});
336
337
ensureNoDisposablesAreLeakedInTestSuite();
338
339
setup(() => {
340
testDisposables = new DisposableStore();
341
instantiationService = setupInstantiationService(testDisposables);
342
config = new TestConfigurationService();
343
instantiationService.stub(IConfigurationService, config);
344
});
345
346
test('simple', () => {
347
const rangeMap = new NotebookCellsLayout(0);
348
rangeMap.splice(0, 0, [{ size: 479 }, { size: 163 }, { size: 182 }, { size: 106 }, { size: 106 }, { size: 106 }, { size: 87 }]);
349
350
const start = rangeMap.indexAt(650);
351
const end = rangeMap.indexAfter(650 + 890 - 1);
352
assert.strictEqual(start, 2);
353
assert.strictEqual(end, 7);
354
355
rangeMap.insertWhitespace('1', 0, 18);
356
assert.strictEqual(rangeMap.indexAt(650), 1);
357
});
358
359
test('Whitespace CRUD', async function () {
360
const twenty = { size: 20 };
361
362
const rangeMap = new NotebookCellsLayout(0);
363
rangeMap.splice(0, 0, [twenty, twenty, twenty]);
364
rangeMap.insertWhitespace('0', 0, 5);
365
rangeMap.insertWhitespace('1', 0, 5);
366
assert.strictEqual(rangeMap.indexAt(0), 0);
367
assert.strictEqual(rangeMap.indexAt(1), 0);
368
assert.strictEqual(rangeMap.indexAt(10), 0);
369
assert.strictEqual(rangeMap.indexAt(11), 0);
370
assert.strictEqual(rangeMap.indexAt(21), 0);
371
assert.strictEqual(rangeMap.indexAt(31), 1);
372
assert.strictEqual(rangeMap.positionAt(0), 10);
373
374
assert.strictEqual(rangeMap.getWhitespacePosition('0'), 0);
375
assert.strictEqual(rangeMap.getWhitespacePosition('1'), 5);
376
377
assert.strictEqual(rangeMap.positionAt(0), 10);
378
assert.strictEqual(rangeMap.positionAt(1), 30);
379
380
rangeMap.changeOneWhitespace('0', 0, 10);
381
assert.strictEqual(rangeMap.getWhitespacePosition('0'), 0);
382
assert.strictEqual(rangeMap.getWhitespacePosition('1'), 10);
383
384
assert.strictEqual(rangeMap.positionAt(0), 15);
385
assert.strictEqual(rangeMap.positionAt(1), 35);
386
387
rangeMap.removeWhitespace('1');
388
assert.strictEqual(rangeMap.getWhitespacePosition('0'), 0);
389
390
assert.strictEqual(rangeMap.positionAt(0), 10);
391
assert.strictEqual(rangeMap.positionAt(1), 30);
392
});
393
394
test('Whitespace with editing', async function () {
395
await withTestNotebook(
396
[
397
['# header a', 'markdown', CellKind.Markup, [], {}],
398
['var b = 1;', 'javascript', CellKind.Code, [], {}],
399
['# header b', 'markdown', CellKind.Markup, [], {}],
400
['var b = 2;', 'javascript', CellKind.Code, [], {}],
401
['# header c', 'markdown', CellKind.Markup, [], {}]
402
],
403
async (editor, viewModel, disposables) => {
404
viewModel.restoreEditorViewState({
405
editingCells: [false, false, false, false, false],
406
cellLineNumberStates: {},
407
editorViewStates: [null, null, null, null, null],
408
cellTotalHeights: [50, 100, 50, 100, 50],
409
collapsedInputCells: {},
410
collapsedOutputCells: {},
411
});
412
413
const cellList = createNotebookCellList(instantiationService, disposables);
414
disposables.add(cellList);
415
cellList.attachViewModel(viewModel);
416
417
// render height 210, it can render 3 full cells and 1 partial cell
418
cellList.layout(210, 100);
419
assert.strictEqual(cellList.scrollHeight, 350);
420
421
cellList.changeViewZones(accessor => {
422
const id = accessor.addZone({
423
afterModelPosition: 1,
424
heightInPx: 20,
425
domNode: document.createElement('div')
426
});
427
428
accessor.layoutZone(id);
429
assert.strictEqual(cellList.scrollHeight, 370);
430
431
assert.strictEqual(cellList.getElementTop(0), 0);
432
assert.strictEqual(cellList.getElementTop(1), 70);
433
assert.strictEqual(cellList.getElementTop(2), 170);
434
435
const textModel = editor.textModel;
436
textModel.applyEdits([
437
{ editType: CellEditType.Replace, index: 0, count: 1, cells: [] },
438
], true, undefined, () => undefined, undefined, true);
439
440
assert.strictEqual(cellList.getElementTop(0), 20);
441
assert.strictEqual(cellList.getElementTop(1), 120);
442
assert.strictEqual(cellList.getElementTop(2), 170);
443
444
accessor.removeZone(id);
445
});
446
});
447
});
448
449
test('Multiple Whitespaces', async function () {
450
await withTestNotebook(
451
[
452
['# header a', 'markdown', CellKind.Markup, [], {}],
453
['var b = 1;', 'javascript', CellKind.Code, [], {}],
454
['# header b', 'markdown', CellKind.Markup, [], {}],
455
['var b = 2;', 'javascript', CellKind.Code, [], {}],
456
['# header c', 'markdown', CellKind.Markup, [], {}]
457
],
458
async (editor, viewModel, disposables) => {
459
viewModel.restoreEditorViewState({
460
editingCells: [false, false, false, false, false],
461
cellLineNumberStates: {},
462
editorViewStates: [null, null, null, null, null],
463
cellTotalHeights: [50, 100, 50, 100, 50],
464
collapsedInputCells: {},
465
collapsedOutputCells: {},
466
});
467
468
const cellList = createNotebookCellList(instantiationService, disposables);
469
disposables.add(cellList);
470
cellList.attachViewModel(viewModel);
471
472
// render height 210, it can render 3 full cells and 1 partial cell
473
cellList.layout(210, 100);
474
assert.strictEqual(cellList.scrollHeight, 350);
475
476
cellList.changeViewZones(accessor => {
477
const first = accessor.addZone({
478
afterModelPosition: 0,
479
heightInPx: 20,
480
domNode: document.createElement('div')
481
});
482
accessor.layoutZone(first);
483
484
const second = accessor.addZone({
485
afterModelPosition: 3,
486
heightInPx: 20,
487
domNode: document.createElement('div')
488
});
489
accessor.layoutZone(second);
490
491
assert.strictEqual(cellList.scrollHeight, 390);
492
493
assert.strictEqual(cellList.getElementTop(0), 20);
494
assert.strictEqual(cellList.getElementTop(1), 70);
495
assert.strictEqual(cellList.getElementTop(2), 170);
496
assert.strictEqual(cellList.getElementTop(3), 240);
497
498
accessor.removeZone(first);
499
500
assert.strictEqual(cellList.scrollHeight, 370);
501
assert.strictEqual(cellList.getElementTop(0), 0);
502
assert.strictEqual(cellList.getElementTop(1), 50);
503
assert.strictEqual(cellList.getElementTop(2), 150);
504
assert.strictEqual(cellList.getElementTop(3), 220);
505
506
accessor.removeZone(second);
507
508
assert.strictEqual(cellList.scrollHeight, 350);
509
assert.strictEqual(cellList.getElementTop(3), 200);
510
});
511
});
512
});
513
514
test('Multiple Whitespaces 2', async function () {
515
await withTestNotebook(
516
[
517
['# header a', 'markdown', CellKind.Markup, [], {}],
518
['var b = 1;', 'javascript', CellKind.Code, [], {}],
519
['# header b', 'markdown', CellKind.Markup, [], {}],
520
['var b = 2;', 'javascript', CellKind.Code, [], {}],
521
['# header c', 'markdown', CellKind.Markup, [], {}]
522
],
523
async (editor, viewModel, disposables) => {
524
viewModel.restoreEditorViewState({
525
editingCells: [false, false, false, false, false],
526
cellLineNumberStates: {},
527
editorViewStates: [null, null, null, null, null],
528
cellTotalHeights: [50, 100, 50, 100, 50],
529
collapsedInputCells: {},
530
collapsedOutputCells: {},
531
});
532
533
const cellList = createNotebookCellList(instantiationService, disposables);
534
disposables.add(cellList);
535
cellList.attachViewModel(viewModel);
536
537
// render height 210, it can render 3 full cells and 1 partial cell
538
cellList.layout(210, 100);
539
assert.strictEqual(cellList.scrollHeight, 350);
540
541
cellList.changeViewZones(accessor => {
542
const first = accessor.addZone({
543
afterModelPosition: 0,
544
heightInPx: 20,
545
domNode: document.createElement('div')
546
});
547
accessor.layoutZone(first);
548
549
const second = accessor.addZone({
550
afterModelPosition: 1,
551
heightInPx: 20,
552
domNode: document.createElement('div')
553
});
554
accessor.layoutZone(second);
555
556
assert.strictEqual(cellList.scrollHeight, 390);
557
assert.strictEqual(cellList._getView().getWhitespacePosition(first), 0);
558
assert.strictEqual(cellList._getView().getWhitespacePosition(second), 70);
559
560
accessor.removeZone(first);
561
accessor.removeZone(second);
562
});
563
});
564
});
565
566
test('Multiple Whitespaces 3', async function () {
567
await withTestNotebook(
568
[
569
['# header a', 'markdown', CellKind.Markup, [], {}],
570
['var b = 1;', 'javascript', CellKind.Code, [], {}],
571
['# header b', 'markdown', CellKind.Markup, [], {}],
572
['var b = 2;', 'javascript', CellKind.Code, [], {}],
573
['# header c', 'markdown', CellKind.Markup, [], {}]
574
],
575
async (editor, viewModel, disposables) => {
576
viewModel.restoreEditorViewState({
577
editingCells: [false, false, false, false, false],
578
cellLineNumberStates: {},
579
editorViewStates: [null, null, null, null, null],
580
cellTotalHeights: [50, 100, 50, 100, 50],
581
collapsedInputCells: {},
582
collapsedOutputCells: {},
583
});
584
585
const cellList = createNotebookCellList(instantiationService, disposables);
586
disposables.add(cellList);
587
cellList.attachViewModel(viewModel);
588
589
// render height 210, it can render 3 full cells and 1 partial cell
590
cellList.layout(210, 100);
591
assert.strictEqual(cellList.scrollHeight, 350);
592
593
cellList.changeViewZones(accessor => {
594
const first = accessor.addZone({
595
afterModelPosition: 1,
596
heightInPx: 20,
597
domNode: document.createElement('div')
598
});
599
accessor.layoutZone(first);
600
601
const second = accessor.addZone({
602
afterModelPosition: 2,
603
heightInPx: 20,
604
domNode: document.createElement('div')
605
});
606
accessor.layoutZone(second);
607
608
assert.strictEqual(cellList.scrollHeight, 390);
609
assert.strictEqual(cellList._getView().getWhitespacePosition(first), 50);
610
assert.strictEqual(cellList._getView().getWhitespacePosition(second), 170);
611
612
accessor.removeZone(first);
613
accessor.removeZone(second);
614
});
615
});
616
});
617
618
// test('Multiple Whitespaces 4', async function () {
619
// await withTestNotebook(
620
// [
621
// ['# header a', 'markdown', CellKind.Markup, [], {}],
622
// ['var b = 1;', 'javascript', CellKind.Code, [], {}],
623
// ['# header b', 'markdown', CellKind.Markup, [], {}],
624
// ['var b = 2;', 'javascript', CellKind.Code, [], {}],
625
// ['# header c', 'markdown', CellKind.Markup, [], {}]
626
// ],
627
// async (editor, viewModel, disposables) => {
628
// viewModel.restoreEditorViewState({
629
// editingCells: [false, false, false, false, false],
630
// cellLineNumberStates: {},
631
// editorViewStates: [null, null, null, null, null],
632
// cellTotalHeights: [50, 100, 50, 100, 50],
633
// collapsedInputCells: {},
634
// collapsedOutputCells: {},
635
// });
636
637
// const cellList = createNotebookCellList(instantiationService, disposables);
638
// disposables.add(cellList);
639
// cellList.attachViewModel(viewModel);
640
641
// // render height 210, it can render 3 full cells and 1 partial cell
642
// cellList.layout(210, 100);
643
// assert.strictEqual(cellList.scrollHeight, 350);
644
645
// cellList.changeViewZones(accessor => {
646
// const first = accessor.addZone({
647
// afterModelPosition: 1,
648
// heightInPx: 20,
649
// domNode: document.createElement('div')
650
// });
651
// accessor.layoutZone(first);
652
653
// const second = accessor.addZone({
654
// afterModelPosition: 1,
655
// heightInPx: 20,
656
// domNode: document.createElement('div')
657
// });
658
// accessor.layoutZone(second);
659
660
// const third = accessor.addZone({
661
// afterModelPosition: 2,
662
// heightInPx: 20,
663
// domNode: document.createElement('div')
664
// });
665
// accessor.layoutZone(second);
666
667
// assert.strictEqual(cellList.scrollHeight, 410);
668
// assert.strictEqual(cellList._getView().getWhitespacePosition(first), 50);
669
// assert.strictEqual(cellList._getView().getWhitespacePosition(second), 70);
670
// assert.strictEqual(cellList._getView().getWhitespacePosition(third), 190);
671
672
// accessor.removeZone(first);
673
// accessor.removeZone(second);
674
// accessor.removeZone(third);
675
// });
676
// });
677
// });
678
679
test('Whitespace with folding support', async function () {
680
await withTestNotebook(
681
[
682
['# header a', 'markdown', CellKind.Markup, [], {}],
683
['var b = 1;', 'javascript', CellKind.Code, [], {}],
684
['# header b', 'markdown', CellKind.Markup, [], {}],
685
['var b = 2;', 'javascript', CellKind.Code, [], {}],
686
['# header c', 'markdown', CellKind.Markup, [], {}]
687
],
688
async (editor, viewModel, disposables) => {
689
viewModel.restoreEditorViewState({
690
editingCells: [false, false, false, false, false],
691
cellLineNumberStates: {},
692
editorViewStates: [null, null, null, null, null],
693
cellTotalHeights: [50, 100, 50, 100, 50],
694
collapsedInputCells: {},
695
collapsedOutputCells: {},
696
});
697
698
const cellList = createNotebookCellList(instantiationService, disposables);
699
disposables.add(cellList);
700
cellList.attachViewModel(viewModel);
701
702
// render height 210, it can render 3 full cells and 1 partial cell
703
cellList.layout(210, 100);
704
assert.strictEqual(cellList.scrollHeight, 350);
705
706
cellList.changeViewZones(accessor => {
707
const id = accessor.addZone({
708
afterModelPosition: 0,
709
heightInPx: 20,
710
domNode: document.createElement('div')
711
});
712
713
accessor.layoutZone(id);
714
assert.strictEqual(cellList.scrollHeight, 370);
715
716
assert.strictEqual(cellList.getElementTop(0), 20);
717
assert.strictEqual(cellList.getElementTop(1), 70);
718
assert.strictEqual(cellList.getElementTop(2), 170);
719
assert.strictEqual(cellList.getElementTop(3), 220);
720
assert.strictEqual(cellList.getElementTop(4), 320);
721
722
accessor.removeZone(id);
723
assert.strictEqual(cellList.scrollHeight, 350);
724
});
725
726
cellList.changeViewZones(accessor => {
727
const id = accessor.addZone({
728
afterModelPosition: 1,
729
heightInPx: 20,
730
domNode: document.createElement('div')
731
});
732
733
accessor.layoutZone(id);
734
assert.strictEqual(cellList.scrollHeight, 370);
735
736
assert.strictEqual(cellList.getElementTop(0), 0);
737
assert.strictEqual(cellList.getElementTop(1), 70);
738
assert.strictEqual(cellList.getElementTop(2), 170);
739
assert.strictEqual(cellList.getElementTop(3), 220);
740
assert.strictEqual(cellList.getElementTop(4), 320);
741
742
accessor.removeZone(id);
743
assert.strictEqual(cellList.scrollHeight, 350);
744
});
745
746
// Whitespace should be hidden if it's after the header in a folding region
747
cellList.changeViewZones(accessor => {
748
const id = accessor.addZone({
749
afterModelPosition: 3,
750
heightInPx: 20,
751
domNode: document.createElement('div')
752
});
753
754
accessor.layoutZone(id);
755
assert.strictEqual(cellList.scrollHeight, 370);
756
757
const foldingModel = disposables.add(new FoldingModel());
758
foldingModel.attachViewModel(viewModel);
759
foldingModel.applyMemento([{ start: 2, end: 3 }]);
760
viewModel.updateFoldingRanges(foldingModel.regions);
761
assert.deepStrictEqual(viewModel.getHiddenRanges(), [
762
{ start: 3, end: 3 }
763
]);
764
cellList.setHiddenAreas(viewModel.getHiddenRanges(), true);
765
assert.strictEqual(cellList.scrollHeight, 250);
766
767
assert.strictEqual(cellList.getElementTop(0), 0);
768
assert.strictEqual(cellList.getElementTop(1), 50);
769
assert.strictEqual(cellList.getElementTop(2), 150);
770
assert.strictEqual(cellList.getElementTop(3), 200);
771
772
cellList.setHiddenAreas([], true);
773
assert.strictEqual(cellList.scrollHeight, 370);
774
accessor.removeZone(id);
775
assert.strictEqual(cellList.scrollHeight, 350);
776
});
777
778
// Whitespace should not be hidden if it's after the last cell in a folding region
779
cellList.changeViewZones(accessor => {
780
const id = accessor.addZone({
781
afterModelPosition: 4,
782
heightInPx: 20,
783
domNode: document.createElement('div')
784
});
785
786
accessor.layoutZone(id);
787
assert.strictEqual(cellList.scrollHeight, 370);
788
789
const foldingModel = disposables.add(new FoldingModel());
790
foldingModel.attachViewModel(viewModel);
791
foldingModel.applyMemento([{ start: 2, end: 3 }]);
792
viewModel.updateFoldingRanges(foldingModel.regions);
793
assert.deepStrictEqual(viewModel.getHiddenRanges(), [
794
{ start: 3, end: 3 }
795
]);
796
cellList.setHiddenAreas(viewModel.getHiddenRanges(), true);
797
assert.strictEqual(cellList.scrollHeight, 270);
798
799
assert.strictEqual(cellList.getElementTop(0), 0);
800
assert.strictEqual(cellList.getElementTop(1), 50);
801
assert.strictEqual(cellList.getElementTop(2), 150);
802
assert.strictEqual(cellList.getElementTop(3), 220);
803
804
cellList.setHiddenAreas([], true);
805
assert.strictEqual(cellList.scrollHeight, 370);
806
accessor.removeZone(id);
807
assert.strictEqual(cellList.scrollHeight, 350);
808
});
809
810
// Whitespace move when previous folding regions fold
811
cellList.changeViewZones(accessor => {
812
const id = accessor.addZone({
813
afterModelPosition: 4,
814
heightInPx: 20,
815
domNode: document.createElement('div')
816
});
817
818
accessor.layoutZone(id);
819
assert.strictEqual(cellList.scrollHeight, 370);
820
821
const foldingModel = disposables.add(new FoldingModel());
822
foldingModel.attachViewModel(viewModel);
823
foldingModel.applyMemento([{ start: 0, end: 1 }]);
824
viewModel.updateFoldingRanges(foldingModel.regions);
825
assert.deepStrictEqual(viewModel.getHiddenRanges(), [
826
{ start: 1, end: 1 }
827
]);
828
cellList.setHiddenAreas(viewModel.getHiddenRanges(), true);
829
assert.strictEqual(cellList.scrollHeight, 270);
830
831
assert.strictEqual(cellList.getElementTop(0), 0);
832
assert.strictEqual(cellList.getElementTop(1), 50);
833
assert.strictEqual(cellList.getElementTop(2), 100);
834
assert.strictEqual(cellList.getElementTop(3), 220);
835
836
cellList.setHiddenAreas([], true);
837
assert.strictEqual(cellList.scrollHeight, 370);
838
accessor.removeZone(id);
839
assert.strictEqual(cellList.scrollHeight, 350);
840
});
841
});
842
});
843
844
test('Whitespace with multiple viewzones at same position', async function () {
845
await withTestNotebook(
846
[
847
['# header a', 'markdown', CellKind.Markup, [], {}],
848
['var b = 1;', 'javascript', CellKind.Code, [], {}],
849
['# header b', 'markdown', CellKind.Markup, [], {}],
850
['var b = 2;', 'javascript', CellKind.Code, [], {}],
851
['# header c', 'markdown', CellKind.Markup, [], {}]
852
],
853
async (editor, viewModel, disposables) => {
854
viewModel.restoreEditorViewState({
855
editingCells: [false, false, false, false, false],
856
cellLineNumberStates: {},
857
editorViewStates: [null, null, null, null, null],
858
cellTotalHeights: [50, 100, 50, 100, 50],
859
collapsedInputCells: {},
860
collapsedOutputCells: {},
861
});
862
863
const cellList = createNotebookCellList(instantiationService, disposables);
864
disposables.add(cellList);
865
cellList.attachViewModel(viewModel);
866
867
// render height 210, it can render 3 full cells and 1 partial cell
868
cellList.layout(210, 100);
869
assert.strictEqual(cellList.scrollHeight, 350);
870
871
cellList.changeViewZones(accessor => {
872
const first = accessor.addZone({
873
afterModelPosition: 0,
874
heightInPx: 20,
875
domNode: document.createElement('div')
876
});
877
878
accessor.layoutZone(first);
879
assert.strictEqual(cellList.scrollHeight, 370);
880
881
const second = accessor.addZone({
882
afterModelPosition: 0,
883
heightInPx: 20,
884
domNode: document.createElement('div')
885
});
886
accessor.layoutZone(second);
887
assert.strictEqual(cellList.scrollHeight, 390);
888
889
assert.strictEqual(cellList.getElementTop(0), 40);
890
assert.strictEqual(cellList.getElementTop(1), 90);
891
assert.strictEqual(cellList.getElementTop(2), 190);
892
assert.strictEqual(cellList.getElementTop(3), 240);
893
assert.strictEqual(cellList.getElementTop(4), 340);
894
895
896
accessor.removeZone(first);
897
assert.strictEqual(cellList.scrollHeight, 370);
898
accessor.removeZone(second);
899
assert.strictEqual(cellList.scrollHeight, 350);
900
});
901
});
902
});
903
});
904
905