@difizen/libro-core 0.1.37 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -12,6 +12,7 @@ import { v4 } from 'uuid';
12
12
  import { LibroCellView, ExecutableCellModel, EditorCellView } from '../cell/index.js';
13
13
  import type { LibroEditorCellView } from '../cell/index.js';
14
14
  import { LibroContextKey } from '../libro-context-key.js';
15
+ import type { LibroModel } from '../libro-model.js';
15
16
  import type { CellView, NotebookView } from '../libro-protocol.js';
16
17
  import { LibroToolbarArea } from '../libro-protocol.js';
17
18
  import { LibroService } from '../libro-service.js';
@@ -37,7 +38,7 @@ export class LibroCommandContribution implements CommandContribution {
37
38
  this.libroService.active?.enterEditMode();
38
39
  },
39
40
  isEnabled: (cell, libro) => {
40
- if (!libro || !(libro instanceof LibroView) || libro.model.readOnly) {
41
+ if (!libro || !(libro instanceof LibroView) || !libro.model.inputEditable) {
41
42
  return false;
42
43
  }
43
44
  return true;
@@ -75,10 +76,12 @@ export class LibroCommandContribution implements CommandContribution {
75
76
  ) {
76
77
  return;
77
78
  }
78
- libro.runCell(cell);
79
+ if ((libro.model as LibroModel).executable) {
80
+ libro.runCell(cell);
81
+ }
79
82
  },
80
83
  isEnabled: (cell, libro) => {
81
- if (!libro || !(libro instanceof LibroView) || libro.model.readOnly) {
84
+ if (!libro || !(libro instanceof LibroView)) {
82
85
  return false;
83
86
  }
84
87
  return true;
@@ -89,7 +92,9 @@ export class LibroCommandContribution implements CommandContribution {
89
92
  if (!libro || !(libro instanceof LibroView)) {
90
93
  return;
91
94
  }
92
- libro.runAllCell();
95
+ if ((libro.model as LibroModel).executable) {
96
+ libro.runAllCell();
97
+ }
93
98
  },
94
99
  });
95
100
  this.libroCommand.registerLibroCommand(command, NotebookCommands['RunAllAbove'], {
@@ -102,7 +107,9 @@ export class LibroCommandContribution implements CommandContribution {
102
107
  ) {
103
108
  return;
104
109
  }
105
- libro.runAllAbove(cell);
110
+ if ((libro.model as LibroModel).executable) {
111
+ libro.runAllAbove(cell);
112
+ }
106
113
  },
107
114
  });
108
115
  this.libroCommand.registerLibroCommand(command, NotebookCommands['RunAllBelow'], {
@@ -115,7 +122,9 @@ export class LibroCommandContribution implements CommandContribution {
115
122
  ) {
116
123
  return;
117
124
  }
118
- libro.runAllBelow(cell);
125
+ if ((libro.model as LibroModel).executable) {
126
+ libro.runAllBelow(cell);
127
+ }
119
128
  },
120
129
  });
121
130
  this.libroCommand.registerLibroCommand(
@@ -131,10 +140,12 @@ export class LibroCommandContribution implements CommandContribution {
131
140
  ) {
132
141
  return;
133
142
  }
134
- libro.runCellandSelectNext(cell);
143
+ if ((libro.model as LibroModel).executable) {
144
+ libro.runCellandSelectNext(cell);
145
+ }
135
146
  },
136
147
  isEnabled: (cell, libro) => {
137
- if (!libro || !(libro instanceof LibroView) || libro.model.readOnly) {
148
+ if (!libro || !(libro instanceof LibroView)) {
138
149
  return false;
139
150
  }
140
151
  return true;
@@ -154,10 +165,12 @@ export class LibroCommandContribution implements CommandContribution {
154
165
  ) {
155
166
  return;
156
167
  }
157
- libro.runCellandInsertBelow(cell);
168
+ if ((libro.model as LibroModel).executable) {
169
+ libro.runCellandInsertBelow(cell);
170
+ }
158
171
  },
159
172
  isEnabled: (cell, libro) => {
160
- if (!libro || !(libro instanceof LibroView) || libro.model.readOnly) {
173
+ if (!libro || !(libro instanceof LibroView)) {
161
174
  return false;
162
175
  }
163
176
  return true;
@@ -190,8 +203,7 @@ export class LibroCommandContribution implements CommandContribution {
190
203
  return false;
191
204
  }
192
205
  return (
193
- !libro?.model.quickEditMode &&
194
- !libro?.model.readOnly &&
206
+ (libro?.model as LibroModel).executable &&
195
207
  path === LibroToolbarArea.HeaderCenter
196
208
  );
197
209
  },
@@ -211,8 +223,7 @@ export class LibroCommandContribution implements CommandContribution {
211
223
  return false;
212
224
  }
213
225
  return (
214
- !libro?.model.quickEditMode &&
215
- !libro?.model.readOnly &&
226
+ (libro?.model as LibroModel).executable &&
216
227
  path === LibroToolbarArea.HeaderCenter
217
228
  );
218
229
  },
@@ -265,10 +276,10 @@ export class LibroCommandContribution implements CommandContribution {
265
276
  if (!libro || !(libro instanceof LibroView)) {
266
277
  return false;
267
278
  }
268
- return !libro?.model.readOnly && path === LibroToolbarArea.CellRight;
279
+ return libro?.model.cellsEditable && path === LibroToolbarArea.CellRight;
269
280
  },
270
281
  isEnabled: (cell, libro) => {
271
- if (!libro || !(libro instanceof LibroView) || libro.model.readOnly) {
282
+ if (!libro || !(libro instanceof LibroView) || !libro.model.cellsEditable) {
272
283
  return false;
273
284
  }
274
285
  return true;
@@ -300,7 +311,7 @@ export class LibroCommandContribution implements CommandContribution {
300
311
  }
301
312
  },
302
313
  isEnabled: (cell, libro) => {
303
- if (!libro || !(libro instanceof LibroView) || libro.model.readOnly) {
314
+ if (!libro || !(libro instanceof LibroView) || !libro.model.cellsEditable) {
304
315
  return false;
305
316
  }
306
317
  return true;
@@ -373,7 +384,12 @@ export class LibroCommandContribution implements CommandContribution {
373
384
  libro.mergeCellBelow(cell);
374
385
  },
375
386
  isEnabled: (cell, libro) => {
376
- if (!libro || !(libro instanceof LibroView) || libro.model.readOnly) {
387
+ if (
388
+ !libro ||
389
+ !(libro instanceof LibroView) ||
390
+ !libro.model.inputEditable ||
391
+ !libro.model.cellsEditable
392
+ ) {
377
393
  return false;
378
394
  }
379
395
  return true;
@@ -396,7 +412,12 @@ export class LibroCommandContribution implements CommandContribution {
396
412
  libro.mergeCellAbove(cell);
397
413
  },
398
414
  isEnabled: (cell, libro) => {
399
- if (!libro || !(libro instanceof LibroView) || libro.model.readOnly) {
415
+ if (
416
+ !libro ||
417
+ !(libro instanceof LibroView) ||
418
+ !libro.model.inputEditable ||
419
+ !libro.model.cellsEditable
420
+ ) {
400
421
  return false;
401
422
  }
402
423
  return true;
@@ -416,7 +437,12 @@ export class LibroCommandContribution implements CommandContribution {
416
437
  libro.mergeCells(cell);
417
438
  },
418
439
  isEnabled: (cell, libro) => {
419
- if (!libro || !(libro instanceof LibroView) || libro.model.readOnly) {
440
+ if (
441
+ !libro ||
442
+ !(libro instanceof LibroView) ||
443
+ !libro.model.inputEditable ||
444
+ !libro.model.cellsEditable
445
+ ) {
420
446
  return false;
421
447
  }
422
448
  return true;
@@ -438,10 +464,10 @@ export class LibroCommandContribution implements CommandContribution {
438
464
  if (!libro || !(libro instanceof LibroView)) {
439
465
  return false;
440
466
  }
441
- return !libro?.model.readOnly && path === LibroToolbarArea.CellRight;
467
+ return libro?.model.cellsEditable && path === LibroToolbarArea.CellRight;
442
468
  },
443
469
  isEnabled: (cell, libro) => {
444
- if (!libro || !(libro instanceof LibroView) || libro.model.readOnly) {
470
+ if (!libro || !(libro instanceof LibroView) || !libro.model.cellsEditable) {
445
471
  return false;
446
472
  }
447
473
  return true;
@@ -463,7 +489,7 @@ export class LibroCommandContribution implements CommandContribution {
463
489
  libro.clearOutputs(cell);
464
490
  },
465
491
  isEnabled: (cell, libro) => {
466
- if (!libro || !(libro instanceof LibroView) || libro.model.readOnly) {
492
+ if (!libro || !(libro instanceof LibroView) || !libro.model.outputEditable) {
467
493
  return false;
468
494
  }
469
495
  return true;
@@ -489,10 +515,10 @@ export class LibroCommandContribution implements CommandContribution {
489
515
  if (!libro || !(libro instanceof LibroView)) {
490
516
  return false;
491
517
  }
492
- return !libro?.model.readOnly && path === LibroToolbarArea.HeaderCenter;
518
+ return libro?.model.outputEditable && path === LibroToolbarArea.HeaderCenter;
493
519
  },
494
520
  isEnabled: (cell, libro) => {
495
- if (!libro || !(libro instanceof LibroView) || libro.model.readOnly) {
521
+ if (!libro || !(libro instanceof LibroView) || !libro.model.outputEditable) {
496
522
  return false;
497
523
  }
498
524
  return true;
@@ -520,7 +546,7 @@ export class LibroCommandContribution implements CommandContribution {
520
546
  !libro ||
521
547
  !(cell instanceof LibroCellView) ||
522
548
  !(libro instanceof LibroView) ||
523
- libro.model.readOnly
549
+ !libro.model.cellsEditable
524
550
  ) {
525
551
  return false;
526
552
  }
@@ -548,7 +574,7 @@ export class LibroCommandContribution implements CommandContribution {
548
574
  !libro ||
549
575
  !(cell instanceof LibroCellView) ||
550
576
  !(libro instanceof LibroView) ||
551
- libro.model.readOnly
577
+ !libro.model.cellsEditable
552
578
  ) {
553
579
  return false;
554
580
  }
@@ -583,7 +609,7 @@ export class LibroCommandContribution implements CommandContribution {
583
609
  // return true;
584
610
  // },
585
611
  isEnabled: (cell, libro) => {
586
- if (!libro || !(libro instanceof LibroView) || libro.model.readOnly) {
612
+ if (!libro || !(libro instanceof LibroView) || !libro.model.cellsEditable) {
587
613
  return false;
588
614
  }
589
615
  return true;
@@ -611,7 +637,7 @@ export class LibroCommandContribution implements CommandContribution {
611
637
  // return true;
612
638
  // },
613
639
  isEnabled: (cell, libro) => {
614
- if (!libro || !(libro instanceof LibroView) || libro.model.readOnly) {
640
+ if (!libro || !(libro instanceof LibroView) || !libro.model.cellsEditable) {
615
641
  return false;
616
642
  }
617
643
  return true;
@@ -633,7 +659,7 @@ export class LibroCommandContribution implements CommandContribution {
633
659
  libro.pasteCellAbove(cell);
634
660
  },
635
661
  isEnabled: (cell, libro) => {
636
- if (!libro || !(libro instanceof LibroView) || libro.model.readOnly) {
662
+ if (!libro || !(libro instanceof LibroView) || !libro.model.cellsEditable) {
637
663
  return false;
638
664
  }
639
665
  return true;
@@ -665,7 +691,7 @@ export class LibroCommandContribution implements CommandContribution {
665
691
  // return true;
666
692
  // },
667
693
  isEnabled: (cell, libro) => {
668
- if (!libro || !(libro instanceof LibroView) || libro.model.readOnly) {
694
+ if (!libro || !(libro instanceof LibroView) || !libro.model.cellsEditable) {
669
695
  return false;
670
696
  }
671
697
  return true;
@@ -795,10 +821,10 @@ export class LibroCommandContribution implements CommandContribution {
795
821
  if (!libro || !(libro instanceof LibroView)) {
796
822
  return false;
797
823
  }
798
- return !libro?.model.readOnly && path === LibroToolbarArea.HeaderCenter;
824
+ return path === LibroToolbarArea.HeaderCenter;
799
825
  },
800
826
  isEnabled: (cell, libro) => {
801
- if (!libro || !(libro instanceof LibroView) || libro.model.readOnly) {
827
+ if (!libro || !(libro instanceof LibroView)) {
802
828
  return false;
803
829
  }
804
830
  return true;
@@ -955,10 +981,10 @@ export class LibroCommandContribution implements CommandContribution {
955
981
  if (!libro || !(libro instanceof LibroView)) {
956
982
  return false;
957
983
  }
958
- return !libro?.model.readOnly && path === LibroToolbarArea.HeaderCenter;
984
+ return libro?.model.cellsEditable && path === LibroToolbarArea.HeaderCenter;
959
985
  },
960
986
  isEnabled: (cell, libro) => {
961
- if (!libro || !(libro instanceof LibroView) || libro.model.readOnly) {
987
+ if (!libro || !(libro instanceof LibroView) || !libro.model.cellsEditable) {
962
988
  return false;
963
989
  }
964
990
  return true;
@@ -980,7 +1006,7 @@ export class LibroCommandContribution implements CommandContribution {
980
1006
  libro.invertCell(cell, 'code');
981
1007
  },
982
1008
  isEnabled: (cell, libro) => {
983
- if (!libro || !(libro instanceof LibroView) || libro.model.readOnly) {
1009
+ if (!libro || !(libro instanceof LibroView) || !libro.model.cellsEditable) {
984
1010
  return false;
985
1011
  }
986
1012
  return true;
@@ -1003,7 +1029,7 @@ export class LibroCommandContribution implements CommandContribution {
1003
1029
  libro.invertCell(cell, 'markdown');
1004
1030
  },
1005
1031
  isEnabled: (cell, libro) => {
1006
- if (!libro || !(libro instanceof LibroView) || libro.model.readOnly) {
1032
+ if (!libro || !(libro instanceof LibroView) || !libro.model.cellsEditable) {
1007
1033
  return false;
1008
1034
  }
1009
1035
  return true;
@@ -1067,25 +1093,25 @@ export class LibroCommandContribution implements CommandContribution {
1067
1093
  if (!libro || !(libro instanceof LibroView)) {
1068
1094
  return false;
1069
1095
  }
1070
- return !libro?.model.readOnly && path === LibroToolbarArea.HeaderCenter;
1096
+ return path === LibroToolbarArea.HeaderCenter;
1071
1097
  },
1072
1098
  },
1073
1099
  );
1074
1100
  this.libroCommand.registerLibroCommand(command, DocumentCommands['Save'], {
1075
1101
  execute: async (cell, libro) => {
1076
- if (!libro || !(libro instanceof LibroView)) {
1102
+ if (!libro || !(libro instanceof LibroView) || !libro.model.savable) {
1077
1103
  return;
1078
1104
  }
1079
1105
  libro.save();
1080
1106
  },
1081
1107
  isVisible: (cell, libro, path) => {
1082
- if (!libro || !(libro instanceof LibroView)) {
1108
+ if (!libro || !(libro instanceof LibroView) || !libro.model.savable) {
1083
1109
  return false;
1084
1110
  }
1085
- return !libro?.model.readOnly && path === LibroToolbarArea.HeaderCenter;
1111
+ return libro?.model.savable && path === LibroToolbarArea.HeaderCenter;
1086
1112
  },
1087
1113
  isEnabled: (cell, libro) => {
1088
- if (!libro || !(libro instanceof LibroView) || libro.model.readOnly) {
1114
+ if (!libro || !(libro instanceof LibroView)) {
1089
1115
  return false;
1090
1116
  }
1091
1117
  return true;
@@ -1099,7 +1125,7 @@ export class LibroCommandContribution implements CommandContribution {
1099
1125
  if (!libro || !(libro instanceof LibroView)) {
1100
1126
  return false;
1101
1127
  }
1102
- return !libro?.model.readOnly && path === LibroToolbarArea.HeaderRight;
1128
+ return path === LibroToolbarArea.HeaderRight;
1103
1129
  },
1104
1130
  });
1105
1131
  this.libroCommand.registerLibroCommand(command, DocumentCommands['FormatCell'], {
@@ -1114,7 +1140,7 @@ export class LibroCommandContribution implements CommandContribution {
1114
1140
  }
1115
1141
  return (
1116
1142
  this.libroService.hasFormatter &&
1117
- !libro?.model.readOnly &&
1143
+ libro?.model.inputEditable &&
1118
1144
  EditorCellView.is(cell) &&
1119
1145
  cell.model.mimeType === MIME.python &&
1120
1146
  path === LibroToolbarArea.CellRight
@@ -1136,10 +1162,10 @@ export class LibroCommandContribution implements CommandContribution {
1136
1162
  if (!libro || !(libro instanceof LibroView)) {
1137
1163
  return false;
1138
1164
  }
1139
- return !libro?.model.readOnly && path === LibroToolbarArea.HeaderCenter;
1165
+ return libro?.model.cellsEditable && path === LibroToolbarArea.HeaderCenter;
1140
1166
  },
1141
1167
  isEnabled: (cell, libro) => {
1142
- if (!libro || !(libro instanceof LibroView) || libro.model.readOnly) {
1168
+ if (!libro || !(libro instanceof LibroView) || !libro.model.cellsEditable) {
1143
1169
  return false;
1144
1170
  }
1145
1171
 
@@ -1161,10 +1187,10 @@ export class LibroCommandContribution implements CommandContribution {
1161
1187
  if (!libro || !(libro instanceof LibroView)) {
1162
1188
  return false;
1163
1189
  }
1164
- return !libro?.model.readOnly && path === LibroToolbarArea.HeaderCenter;
1190
+ return libro?.model.cellsEditable && path === LibroToolbarArea.HeaderCenter;
1165
1191
  },
1166
1192
  isEnabled: (cell, libro) => {
1167
- if (!libro || !(libro instanceof LibroView) || libro.model.readOnly) {
1193
+ if (!libro || !(libro instanceof LibroView) || !libro.model.cellsEditable) {
1168
1194
  return false;
1169
1195
  }
1170
1196
  return libro.model.canRedo ?? false;
@@ -1187,7 +1213,7 @@ export class LibroCommandContribution implements CommandContribution {
1187
1213
  libro.splitCell(cell);
1188
1214
  },
1189
1215
  isEnabled: (cell, libro) => {
1190
- if (!libro || !(libro instanceof LibroView) || libro.model.readOnly) {
1216
+ if (!libro || !(libro instanceof LibroView) || !libro.model.cellsEditable) {
1191
1217
  return false;
1192
1218
  }
1193
1219
  return true;
@@ -1202,7 +1228,7 @@ export class LibroCommandContribution implements CommandContribution {
1202
1228
  (cell as LibroEditorCellView).redo();
1203
1229
  },
1204
1230
  isEnabled: (cell, libro) => {
1205
- if (!libro || !(libro instanceof LibroView) || libro.model.readOnly) {
1231
+ if (!libro || !(libro instanceof LibroView) || !libro.model.inputEditable) {
1206
1232
  return false;
1207
1233
  }
1208
1234
  return true;
@@ -1216,7 +1242,7 @@ export class LibroCommandContribution implements CommandContribution {
1216
1242
  (cell as LibroEditorCellView).undo();
1217
1243
  },
1218
1244
  isEnabled: (cell, libro) => {
1219
- if (!libro || !(libro instanceof LibroView) || libro.model.readOnly) {
1245
+ if (!libro || !(libro instanceof LibroView) || !libro.model.inputEditable) {
1220
1246
  return false;
1221
1247
  }
1222
1248
  return true;
@@ -1238,7 +1264,7 @@ export class LibroCommandContribution implements CommandContribution {
1238
1264
  libro.setMarkdownHeader(cell, 1);
1239
1265
  },
1240
1266
  isEnabled: (cell, libro) => {
1241
- if (!libro || !(libro instanceof LibroView) || libro.model.readOnly) {
1267
+ if (!libro || !(libro instanceof LibroView) || !libro.model.cellsEditable) {
1242
1268
  return false;
1243
1269
  }
1244
1270
  return true;
@@ -1261,7 +1287,7 @@ export class LibroCommandContribution implements CommandContribution {
1261
1287
  libro.setMarkdownHeader(cell, 2);
1262
1288
  },
1263
1289
  isEnabled: (cell, libro) => {
1264
- if (!libro || !(libro instanceof LibroView) || libro.model.readOnly) {
1290
+ if (!libro || !(libro instanceof LibroView) || !libro.model.cellsEditable) {
1265
1291
  return false;
1266
1292
  }
1267
1293
  return true;
@@ -1284,7 +1310,7 @@ export class LibroCommandContribution implements CommandContribution {
1284
1310
  libro.setMarkdownHeader(cell, 3);
1285
1311
  },
1286
1312
  isEnabled: (cell, libro) => {
1287
- if (!libro || !(libro instanceof LibroView) || libro.model.readOnly) {
1313
+ if (!libro || !(libro instanceof LibroView) || !libro.model.cellsEditable) {
1288
1314
  return false;
1289
1315
  }
1290
1316
  return true;
@@ -1307,7 +1333,7 @@ export class LibroCommandContribution implements CommandContribution {
1307
1333
  libro.setMarkdownHeader(cell, 4);
1308
1334
  },
1309
1335
  isEnabled: (cell, libro) => {
1310
- if (!libro || !(libro instanceof LibroView) || libro.model.readOnly) {
1336
+ if (!libro || !(libro instanceof LibroView) || !libro.model.cellsEditable) {
1311
1337
  return false;
1312
1338
  }
1313
1339
  return true;
@@ -1330,7 +1356,7 @@ export class LibroCommandContribution implements CommandContribution {
1330
1356
  libro.setMarkdownHeader(cell, 5);
1331
1357
  },
1332
1358
  isEnabled: (cell, libro) => {
1333
- if (!libro || !(libro instanceof LibroView) || libro.model.readOnly) {
1359
+ if (!libro || !(libro instanceof LibroView) || !libro.model.cellsEditable) {
1334
1360
  return false;
1335
1361
  }
1336
1362
  return true;
@@ -1353,7 +1379,7 @@ export class LibroCommandContribution implements CommandContribution {
1353
1379
  libro.setMarkdownHeader(cell, 6);
1354
1380
  },
1355
1381
  isEnabled: (cell, libro) => {
1356
- if (!libro || !(libro instanceof LibroView) || libro.model.readOnly) {
1382
+ if (!libro || !(libro instanceof LibroView) || !libro.model.cellsEditable) {
1357
1383
  return false;
1358
1384
  }
1359
1385
  return true;
@@ -407,7 +407,7 @@ export const DndCellItemContainer = memo(function DndCellItemContainer(
407
407
  e.stopPropagation();
408
408
  }}
409
409
  >
410
- {isActive && !isDrag && instance.model.readOnly !== true && (
410
+ {isActive && !isDrag && instance.model.cellsEditable && (
411
411
  <ToolbarRender
412
412
  data={rightToolbarArgs}
413
413
  tooltip={{ placement: LibroToolbarArea.CellRight }}
@@ -259,7 +259,7 @@ export const DndCellContainer: React.FC<DndContentProps> = ({ cell, index }) =>
259
259
  },
260
260
  });
261
261
  const opacity = isDrag ? 0.4 : 1;
262
- if (!instance.model.readOnly) {
262
+ if (instance.model.cellsEditable) {
263
263
  drop(ref);
264
264
  }
265
265
  if (isDrag) {
@@ -94,9 +94,28 @@ export class LibroModel implements NotebookModel, DndListModel {
94
94
  lastClipboardInteraction?: string;
95
95
 
96
96
  clipboard?: CellView | CellView[];
97
+ @prop()
98
+ inputEditable = true;
99
+
100
+ @prop()
101
+ outputEditable = true;
97
102
 
98
103
  @prop()
99
- quickEditMode = false;
104
+ cellsEditable = true;
105
+
106
+ get executable() {
107
+ return this.outputEditable && this.runnable;
108
+ }
109
+
110
+ set executable(value: boolean) {
111
+ this.runnable = value;
112
+ }
113
+
114
+ @prop()
115
+ savable = true;
116
+
117
+ @prop()
118
+ runnable = true;
100
119
 
101
120
  @prop()
102
121
  commandMode = true;
@@ -110,9 +129,6 @@ export class LibroModel implements NotebookModel, DndListModel {
110
129
  @prop()
111
130
  dirty = false;
112
131
 
113
- @prop()
114
- readOnly = false;
115
-
116
132
  @prop()
117
133
  cells: CellView[] = [];
118
134
 
@@ -236,7 +252,7 @@ export class LibroModel implements NotebookModel, DndListModel {
236
252
  currpos += delta.retain;
237
253
  }
238
254
  });
239
- if (this.readOnly && !this.isInitialized) {
255
+ if (!this.inputEditable && !this.isInitialized) {
240
256
  this.selectCell(undefined);
241
257
  return;
242
258
  }
@@ -85,16 +85,26 @@ export interface BaseNotebookModel {
85
85
  active?: CellView | undefined;
86
86
  activeIndex: number;
87
87
  dndAreaNullEnable: boolean;
88
+
88
89
  /**
89
- * The read-only state of the model.
90
+ * Controlling whether the cell input is editable
90
91
  */
91
- readOnly: boolean;
92
+ inputEditable: boolean;
93
+
94
+ outputEditable: boolean;
92
95
 
93
96
  /**
94
- * The quick edit mode the model.
97
+ * Controlling whether the cells list is editable
95
98
  */
96
- quickEditMode: boolean;
97
-
99
+ cellsEditable: boolean;
100
+ /**
101
+ * Controlling whether the cells can execute
102
+ */
103
+ runnable: boolean;
104
+ /**
105
+ * Controlling whether the notebook can save
106
+ */
107
+ savable: boolean;
98
108
  /**
99
109
  * The command mode of the model.
100
110
  */
@@ -234,14 +234,23 @@ export const LibroRender = forwardRef<HTMLDivElement>(function LibroRender(props
234
234
  const dndDom = ref?.current?.getElementsByClassName(
235
235
  'libro-dnd-cells-container',
236
236
  )[0];
237
- if (!dndDom?.contains(e.relatedTarget) && instance.model.readOnly) {
237
+ if (
238
+ !dndDom?.contains(e.relatedTarget) &&
239
+ (!instance.model.inputEditable ||
240
+ !instance.model.outputEditable ||
241
+ !instance.model.cellsEditable)
242
+ ) {
238
243
  instance.selectCell(undefined);
239
244
  }
240
245
  } else {
241
246
  instance.enterCommandMode(false);
242
247
  libroService.focus = undefined;
243
248
  instance.onBlurEmitter.fire('');
244
- if (instance.model.readOnly) {
249
+ if (
250
+ !instance.model.inputEditable ||
251
+ !instance.model.outputEditable ||
252
+ !instance.model.cellsEditable
253
+ ) {
245
254
  instance.selectCell(undefined);
246
255
  }
247
256
  }