UNPKG

4.45 kBJavaScriptView Raw
1// Copyright (c) Jupyter Development Team.
2// Distributed under the terms of the Modified BSD License.
3import { CodeCellModel, MarkdownCellModel, RawCellModel } from '@jupyterlab/cells';
4import { Signal } from '@lumino/signaling';
5/**
6 * A cell list object that supports undo/redo.
7 */
8export class CellList {
9 /**
10 * Construct the cell list.
11 */
12 constructor(model) {
13 this.model = model;
14 this._cellMap = new WeakMap();
15 this._changed = new Signal(this);
16 this._isDisposed = false;
17 this._insertCells(0, this.model.cells);
18 this.model.changed.connect(this._onSharedModelChanged, this);
19 }
20 /**
21 * A signal emitted when the cell list has changed.
22 */
23 get changed() {
24 return this._changed;
25 }
26 /**
27 * Test whether the cell list has been disposed.
28 */
29 get isDisposed() {
30 return this._isDisposed;
31 }
32 /**
33 * Get the length of the cell list.
34 *
35 * @returns The number of cells in the cell list.
36 */
37 get length() {
38 return this.model.cells.length;
39 }
40 /**
41 * Create an iterator over the cells in the cell list.
42 *
43 * @returns A new iterator starting at the front of the cell list.
44 */
45 *[Symbol.iterator]() {
46 for (const cell of this.model.cells) {
47 yield this._cellMap.get(cell);
48 }
49 }
50 /**
51 * Dispose of the resources held by the cell list.
52 */
53 dispose() {
54 var _a;
55 if (this._isDisposed) {
56 return;
57 }
58 this._isDisposed = true;
59 // Clean up the cell map and cell order objects.
60 for (const cell of this.model.cells) {
61 (_a = this._cellMap.get(cell)) === null || _a === void 0 ? void 0 : _a.dispose();
62 }
63 Signal.clearData(this);
64 }
65 /**
66 * Get the cell at the specified index.
67 *
68 * @param index - The positive integer index of interest.
69 *
70 * @returns The cell at the specified index.
71 */
72 get(index) {
73 return this._cellMap.get(this.model.cells[index]);
74 }
75 _insertCells(index, cells) {
76 cells.forEach(sharedModel => {
77 let cellModel;
78 switch (sharedModel.cell_type) {
79 case 'code': {
80 cellModel = new CodeCellModel({
81 sharedModel: sharedModel
82 });
83 break;
84 }
85 case 'markdown': {
86 cellModel = new MarkdownCellModel({
87 sharedModel: sharedModel
88 });
89 break;
90 }
91 default: {
92 cellModel = new RawCellModel({
93 sharedModel: sharedModel
94 });
95 }
96 }
97 this._cellMap.set(sharedModel, cellModel);
98 sharedModel.disposed.connect(() => {
99 cellModel.dispose();
100 this._cellMap.delete(sharedModel);
101 });
102 });
103 return this.length;
104 }
105 _onSharedModelChanged(self, change) {
106 var _a;
107 let currpos = 0;
108 // We differ emitting the list changes to ensure cell model for all current shared cell have been created.
109 const events = new Array();
110 (_a = change.cellsChange) === null || _a === void 0 ? void 0 : _a.forEach(delta => {
111 if (delta.insert != null) {
112 this._insertCells(currpos, delta.insert);
113 events.push({
114 type: 'add',
115 newIndex: currpos,
116 newValues: delta.insert.map(c => this._cellMap.get(c)),
117 oldIndex: -2,
118 oldValues: []
119 });
120 currpos += delta.insert.length;
121 }
122 else if (delta.delete != null) {
123 events.push({
124 type: 'remove',
125 newIndex: -1,
126 newValues: [],
127 oldIndex: currpos,
128 // Cells have been disposed, so we don't know which one are gone.
129 oldValues: new Array(delta.delete).fill(undefined)
130 });
131 }
132 else if (delta.retain != null) {
133 currpos += delta.retain;
134 }
135 });
136 events.forEach(msg => this._changed.emit(msg));
137 }
138}
139//# sourceMappingURL=celllist.js.map
\No newline at end of file