@theia/notebook 1.43.1 → 1.45.0

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.
Files changed (104) hide show
  1. package/lib/browser/contributions/notebook-actions-contribution.d.ts +2 -2
  2. package/lib/browser/contributions/notebook-actions-contribution.d.ts.map +1 -1
  3. package/lib/browser/contributions/notebook-actions-contribution.js +1 -1
  4. package/lib/browser/contributions/notebook-actions-contribution.js.map +1 -1
  5. package/lib/browser/index.d.ts +1 -0
  6. package/lib/browser/index.d.ts.map +1 -1
  7. package/lib/browser/index.js +1 -0
  8. package/lib/browser/index.js.map +1 -1
  9. package/lib/browser/notebook-editor-widget.d.ts +4 -1
  10. package/lib/browser/notebook-editor-widget.d.ts.map +1 -1
  11. package/lib/browser/notebook-editor-widget.js +9 -3
  12. package/lib/browser/notebook-editor-widget.js.map +1 -1
  13. package/lib/browser/notebook-frontend-module.js +1 -1
  14. package/lib/browser/notebook-frontend-module.js.map +1 -1
  15. package/lib/browser/notebook-output-utils.d.ts +13 -0
  16. package/lib/browser/notebook-output-utils.d.ts.map +1 -0
  17. package/lib/browser/notebook-output-utils.js +112 -0
  18. package/lib/browser/notebook-output-utils.js.map +1 -0
  19. package/lib/browser/notebook-types.d.ts +120 -0
  20. package/lib/browser/notebook-types.d.ts.map +1 -0
  21. package/lib/browser/notebook-types.js +28 -0
  22. package/lib/browser/notebook-types.js.map +1 -0
  23. package/lib/browser/service/notebook-cell-context-manager.d.ts +5 -4
  24. package/lib/browser/service/notebook-cell-context-manager.d.ts.map +1 -1
  25. package/lib/browser/service/notebook-cell-context-manager.js +15 -10
  26. package/lib/browser/service/notebook-cell-context-manager.js.map +1 -1
  27. package/lib/browser/service/notebook-editor-widget-service.d.ts +2 -5
  28. package/lib/browser/service/notebook-editor-widget-service.d.ts.map +1 -1
  29. package/lib/browser/service/notebook-editor-widget-service.js +12 -15
  30. package/lib/browser/service/notebook-editor-widget-service.js.map +1 -1
  31. package/lib/browser/service/notebook-execution-service.d.ts +3 -4
  32. package/lib/browser/service/notebook-execution-service.d.ts.map +1 -1
  33. package/lib/browser/service/notebook-execution-service.js +2 -12
  34. package/lib/browser/service/notebook-execution-service.js.map +1 -1
  35. package/lib/browser/service/notebook-execution-state-service.d.ts +2 -5
  36. package/lib/browser/service/notebook-execution-state-service.d.ts.map +1 -1
  37. package/lib/browser/service/notebook-execution-state-service.js.map +1 -1
  38. package/lib/browser/service/notebook-kernel-history-service.d.ts +4 -1
  39. package/lib/browser/service/notebook-kernel-history-service.d.ts.map +1 -1
  40. package/lib/browser/service/notebook-kernel-history-service.js +15 -0
  41. package/lib/browser/service/notebook-kernel-history-service.js.map +1 -1
  42. package/lib/browser/service/notebook-kernel-quick-pick-service.d.ts +5 -11
  43. package/lib/browser/service/notebook-kernel-quick-pick-service.d.ts.map +1 -1
  44. package/lib/browser/service/notebook-kernel-quick-pick-service.js +33 -48
  45. package/lib/browser/service/notebook-kernel-quick-pick-service.js.map +1 -1
  46. package/lib/browser/service/notebook-service.d.ts.map +1 -1
  47. package/lib/browser/service/notebook-service.js +9 -4
  48. package/lib/browser/service/notebook-service.js.map +1 -1
  49. package/lib/browser/view/notebook-cell-editor.d.ts +1 -1
  50. package/lib/browser/view/notebook-cell-editor.d.ts.map +1 -1
  51. package/lib/browser/view/notebook-cell-editor.js +5 -5
  52. package/lib/browser/view/notebook-cell-editor.js.map +1 -1
  53. package/lib/browser/view/notebook-cell-list-view.d.ts.map +1 -1
  54. package/lib/browser/view/notebook-cell-list-view.js +9 -3
  55. package/lib/browser/view/notebook-cell-list-view.js.map +1 -1
  56. package/lib/browser/view/notebook-cell-toolbar-factory.d.ts +1 -0
  57. package/lib/browser/view/notebook-cell-toolbar-factory.d.ts.map +1 -1
  58. package/lib/browser/view/notebook-cell-toolbar-factory.js +2 -1
  59. package/lib/browser/view/notebook-cell-toolbar-factory.js.map +1 -1
  60. package/lib/browser/view/notebook-cell-toolbar.d.ts +5 -4
  61. package/lib/browser/view/notebook-cell-toolbar.d.ts.map +1 -1
  62. package/lib/browser/view/notebook-cell-toolbar.js +6 -4
  63. package/lib/browser/view/notebook-cell-toolbar.js.map +1 -1
  64. package/lib/browser/view/notebook-main-toolbar.d.ts.map +1 -1
  65. package/lib/browser/view/notebook-main-toolbar.js +8 -0
  66. package/lib/browser/view/notebook-main-toolbar.js.map +1 -1
  67. package/lib/browser/view-model/notebook-cell-model.d.ts +22 -2
  68. package/lib/browser/view-model/notebook-cell-model.d.ts.map +1 -1
  69. package/lib/browser/view-model/notebook-cell-model.js +5 -0
  70. package/lib/browser/view-model/notebook-cell-model.js.map +1 -1
  71. package/lib/browser/view-model/notebook-cell-output-model.d.ts.map +1 -1
  72. package/lib/browser/view-model/notebook-cell-output-model.js +4 -3
  73. package/lib/browser/view-model/notebook-cell-output-model.js.map +1 -1
  74. package/lib/browser/view-model/notebook-model.d.ts +9 -7
  75. package/lib/browser/view-model/notebook-model.d.ts.map +1 -1
  76. package/lib/browser/view-model/notebook-model.js +42 -36
  77. package/lib/browser/view-model/notebook-model.js.map +1 -1
  78. package/lib/common/notebook-common.d.ts +14 -146
  79. package/lib/common/notebook-common.d.ts.map +1 -1
  80. package/lib/common/notebook-common.js +13 -9
  81. package/lib/common/notebook-common.js.map +1 -1
  82. package/package.json +7 -7
  83. package/src/browser/contributions/notebook-actions-contribution.ts +2 -2
  84. package/src/browser/index.ts +1 -0
  85. package/src/browser/notebook-editor-widget.tsx +11 -5
  86. package/src/browser/notebook-frontend-module.ts +2 -2
  87. package/src/browser/notebook-output-utils.ts +119 -0
  88. package/src/browser/notebook-types.ts +172 -0
  89. package/src/browser/service/notebook-cell-context-manager.ts +17 -12
  90. package/src/browser/service/notebook-editor-widget-service.ts +14 -19
  91. package/src/browser/service/notebook-execution-service.ts +4 -16
  92. package/src/browser/service/notebook-execution-state-service.ts +2 -5
  93. package/src/browser/service/notebook-kernel-history-service.ts +18 -1
  94. package/src/browser/service/notebook-kernel-quick-pick-service.ts +29 -49
  95. package/src/browser/service/notebook-service.ts +13 -4
  96. package/src/browser/view/notebook-cell-editor.tsx +7 -5
  97. package/src/browser/view/notebook-cell-list-view.tsx +8 -3
  98. package/src/browser/view/notebook-cell-toolbar-factory.tsx +3 -1
  99. package/src/browser/view/notebook-cell-toolbar.tsx +8 -5
  100. package/src/browser/view/notebook-main-toolbar.tsx +9 -0
  101. package/src/browser/view-model/notebook-cell-model.ts +30 -3
  102. package/src/browser/view-model/notebook-cell-output-model.ts +6 -5
  103. package/src/browser/view-model/notebook-model.ts +52 -45
  104. package/src/common/notebook-common.ts +22 -181
@@ -21,7 +21,9 @@
21
21
  import { inject, injectable, postConstruct } from '@theia/core/shared/inversify';
22
22
  import { StorageService } from '@theia/core/lib/browser';
23
23
  import { NotebookKernel, NotebookTextModelLike, NotebookKernelService } from './notebook-kernel-service';
24
- import { Disposable } from '@theia/core';
24
+ import { CommandService, Disposable } from '@theia/core';
25
+ import { NotebookModel } from '../view-model/notebook-model';
26
+ import { NotebookCommands } from '../contributions/notebook-actions-contribution';
25
27
 
26
28
  interface KernelsList {
27
29
  [viewType: string]: string[];
@@ -43,6 +45,9 @@ export class NotebookKernelHistoryService implements Disposable {
43
45
  @inject(NotebookKernelService)
44
46
  protected notebookKernelService: NotebookKernelService;
45
47
 
48
+ @inject(CommandService)
49
+ protected commandService: CommandService;
50
+
46
51
  declare serviceBrand: undefined;
47
52
 
48
53
  private static STORAGE_KEY = 'notebook.kernelHistory';
@@ -68,6 +73,18 @@ export class NotebookKernelHistoryService implements Disposable {
68
73
  };
69
74
  }
70
75
 
76
+ async resolveSelectedKernel(notebook: NotebookModel): Promise<NotebookKernel | undefined> {
77
+ const alreadySelected = this.getKernels(notebook);
78
+
79
+ if (alreadySelected.selected) {
80
+ return alreadySelected.selected;
81
+ }
82
+
83
+ await this.commandService.executeCommand(NotebookCommands.SELECT_KERNEL_COMMAND.id, notebook);
84
+ const { selected } = this.getKernels(notebook);
85
+ return selected;
86
+ }
87
+
71
88
  addMostRecentKernel(kernel: NotebookKernel): void {
72
89
  const viewType = kernel.viewType;
73
90
  const recentKernels = this.mostRecentKernelsMap[viewType] ?? [kernel.id];
@@ -18,19 +18,18 @@
18
18
  * Copyright (c) Microsoft Corporation. All rights reserved.
19
19
  * Licensed under the MIT License. See License.txt in the project root for license information.
20
20
  *--------------------------------------------------------------------------------------------*/
21
- import { ArrayUtils, Command, CommandService, DisposableCollection, Event, nls, QuickInputButton, QuickInputService, QuickPickInput, QuickPickItem, URI, } from '@theia/core';
21
+ import { ArrayUtils, CommandService, DisposableCollection, Event, nls, QuickInputButton, QuickInputService, QuickPickInput, QuickPickItem, URI, } from '@theia/core';
22
22
  import { inject, injectable } from '@theia/core/shared/inversify';
23
23
  import { NotebookKernelService, NotebookKernel, NotebookKernelMatchResult, SourceCommand } from './notebook-kernel-service';
24
24
  import { NotebookModel } from '../view-model/notebook-model';
25
25
  import { NotebookEditorWidget } from '../notebook-editor-widget';
26
26
  import { codicon, OpenerService } from '@theia/core/lib/browser';
27
27
  import { NotebookKernelHistoryService } from './notebook-kernel-history-service';
28
+ import { NotebookCommand, NotebookModelResource } from '../../common';
28
29
  import debounce = require('@theia/core/shared/lodash.debounce');
29
30
 
30
31
  export const JUPYTER_EXTENSION_ID = 'ms-toolsai.jupyter';
31
32
 
32
- export const NotebookKernelQuickPickService = Symbol('NotebookKernelQuickPickService');
33
-
34
33
  type KernelPick = QuickPickItem & { kernel: NotebookKernel };
35
34
  function isKernelPick(item: QuickPickInput<QuickPickItem>): item is KernelPick {
36
35
  return 'kernel' in item;
@@ -45,7 +44,7 @@ function isSourcePick(item: QuickPickInput<QuickPickItem>): item is SourcePick {
45
44
  }
46
45
  type InstallExtensionPick = QuickPickItem & { extensionIds: string[] };
47
46
 
48
- type KernelSourceQuickPickItem = QuickPickItem & { command: Command; documentation?: string };
47
+ type KernelSourceQuickPickItem = QuickPickItem & { command: NotebookCommand; documentation?: string };
49
48
  function isKernelSourceQuickPickItem(item: QuickPickItem): item is KernelSourceQuickPickItem {
50
49
  return 'command' in item;
51
50
  }
@@ -82,7 +81,7 @@ function toKernelQuickPick(kernel: NotebookKernel, selected: NotebookKernel | un
82
81
  }
83
82
 
84
83
  @injectable()
85
- export abstract class NotebookKernelQuickPickServiceImpl {
84
+ export class NotebookKernelQuickPickService {
86
85
 
87
86
  @inject(NotebookKernelService)
88
87
  protected readonly notebookKernelService: NotebookKernelService;
@@ -91,6 +90,12 @@ export abstract class NotebookKernelQuickPickServiceImpl {
91
90
  @inject(CommandService)
92
91
  protected readonly commandService: CommandService;
93
92
 
93
+ @inject(OpenerService)
94
+ protected openerService: OpenerService;
95
+
96
+ @inject(NotebookKernelHistoryService)
97
+ protected notebookKernelHistoryService: NotebookKernelHistoryService;
98
+
94
99
  async showQuickPick(editor: NotebookModel, wantedId?: string, skipAutoRun?: boolean): Promise<boolean> {
95
100
  const notebook = editor;
96
101
  const matchResult = this.getMatchingResult(notebook);
@@ -200,40 +205,6 @@ export abstract class NotebookKernelQuickPickServiceImpl {
200
205
  return false;
201
206
  }
202
207
 
203
- protected getMatchingResult(notebook: NotebookModel): NotebookKernelMatchResult {
204
- return this.notebookKernelService.getMatchingKernel(notebook);
205
- }
206
-
207
- protected abstract getKernelPickerQuickPickItems(matchResult: NotebookKernelMatchResult): QuickPickInput<KernelQuickPickItem>[];
208
-
209
- protected async handleQuickPick(editor: NotebookModel, pick: KernelQuickPickItem, quickPickItems: KernelQuickPickItem[]): Promise<boolean> {
210
- if (isKernelPick(pick)) {
211
- const newKernel = pick.kernel;
212
- this.selectKernel(editor, newKernel);
213
- return true;
214
- }
215
-
216
- if (isSourcePick(pick)) {
217
- // selected explicitly, it should trigger the execution?
218
- pick.action.run(this.commandService);
219
- }
220
-
221
- return true;
222
- }
223
-
224
- protected selectKernel(notebook: NotebookModel, kernel: NotebookKernel): void {
225
- this.notebookKernelService.selectKernelForNotebook(kernel, notebook);
226
- }
227
- }
228
- @injectable()
229
- export class KernelPickerMRUStrategy extends NotebookKernelQuickPickServiceImpl {
230
-
231
- @inject(OpenerService)
232
- protected openerService: OpenerService;
233
-
234
- @inject(NotebookKernelHistoryService)
235
- protected notebookKernelHistoryService: NotebookKernelHistoryService;
236
-
237
208
  protected getKernelPickerQuickPickItems(matchResult: NotebookKernelMatchResult): QuickPickInput<KernelQuickPickItem>[] {
238
209
  const quickPickItems: QuickPickInput<KernelQuickPickItem>[] = [];
239
210
 
@@ -266,17 +237,17 @@ export class KernelPickerMRUStrategy extends NotebookKernelQuickPickServiceImpl
266
237
  return quickPickItems;
267
238
  }
268
239
 
269
- protected override selectKernel(notebook: NotebookModel, kernel: NotebookKernel): void {
240
+ protected selectKernel(notebook: NotebookModel, kernel: NotebookKernel): void {
270
241
  const currentInfo = this.notebookKernelService.getMatchingKernel(notebook);
271
242
  if (currentInfo.selected) {
272
243
  // there is already a selected kernel
273
244
  this.notebookKernelHistoryService.addMostRecentKernel(currentInfo.selected);
274
245
  }
275
- super.selectKernel(notebook, kernel);
246
+ this.notebookKernelService.selectKernelForNotebook(kernel, notebook);
276
247
  this.notebookKernelHistoryService.addMostRecentKernel(kernel);
277
248
  }
278
249
 
279
- protected override getMatchingResult(notebook: NotebookModel): NotebookKernelMatchResult {
250
+ protected getMatchingResult(notebook: NotebookModel): NotebookKernelMatchResult {
280
251
  const { selected, all } = this.notebookKernelHistoryService.getKernels(notebook);
281
252
  const matchingResult = this.notebookKernelService.getMatchingKernel(notebook);
282
253
  return {
@@ -287,12 +258,23 @@ export class KernelPickerMRUStrategy extends NotebookKernelQuickPickServiceImpl
287
258
  };
288
259
  }
289
260
 
290
- protected override async handleQuickPick(editor: NotebookModel, pick: KernelQuickPickItem, items: KernelQuickPickItem[]): Promise<boolean> {
261
+ protected async handleQuickPick(editor: NotebookModel, pick: KernelQuickPickItem, items: KernelQuickPickItem[]): Promise<boolean> {
291
262
  if (pick.id === 'selectAnother') {
292
263
  return this.displaySelectAnotherQuickPick(editor, items.length === 1 && items[0] === pick);
293
264
  }
294
265
 
295
- return super.handleQuickPick(editor, pick, items);
266
+ if (isKernelPick(pick)) {
267
+ const newKernel = pick.kernel;
268
+ this.selectKernel(editor, newKernel);
269
+ return true;
270
+ }
271
+
272
+ if (isSourcePick(pick)) {
273
+ // selected explicitly, it should trigger the execution?
274
+ pick.action.run(this.commandService);
275
+ }
276
+
277
+ return true;
296
278
  }
297
279
 
298
280
  private async displaySelectAnotherQuickPick(editor: NotebookModel, kernelListEmpty: boolean): Promise<boolean> {
@@ -488,10 +470,8 @@ export class KernelPickerMRUStrategy extends NotebookKernelQuickPickServiceImpl
488
470
  quickPick.show();
489
471
  }
490
472
 
491
- private async executeCommand<T>(notebook: NotebookModel, command: string | Command): Promise<T | undefined | void> {
492
- const id = typeof command === 'string' ? command : command.id;
493
-
494
- return this.commandService.executeCommand(id, { uri: notebook.uri });
495
-
473
+ private async executeCommand<T>(notebook: NotebookModel, command: NotebookCommand): Promise<T | undefined | void> {
474
+ const args = (command.arguments || []).concat([NotebookModelResource.create(notebook.uri)]);
475
+ return this.commandService.executeCommand(command.id, ...args);
496
476
  }
497
477
  }
@@ -135,22 +135,31 @@ export class NotebookService implements Disposable {
135
135
  if (this.notebookProviders.has(type)) {
136
136
  return this.notebookProviders.get(type);
137
137
  }
138
- await Promise.all(this.willUseNotebookSerializerEmitter.fire(type));
139
138
  const deferred = new Deferred<NotebookProviderInfo | undefined>();
140
139
  // 20 seconds of timeout
141
140
  const timeoutDuration = 20_000;
142
- const disposable = this.onDidRegisterNotebookSerializer(viewType => {
141
+
142
+ // Must declare these variables where they can be captured by the closure
143
+ let disposable: Disposable;
144
+ // eslint-disable-next-line
145
+ let timeout: ReturnType<typeof setTimeout>;
146
+
147
+ // eslint-disable-next-line
148
+ disposable = this.onDidRegisterNotebookSerializer(viewType => {
143
149
  if (viewType === type) {
144
150
  clearTimeout(timeout);
145
151
  disposable.dispose();
146
152
  deferred.resolve(this.notebookProviders.get(type));
147
153
  }
148
154
  });
149
- const timeout = setTimeout(() => {
155
+ timeout = setTimeout(() => {
150
156
  clearTimeout(timeout);
151
157
  disposable.dispose();
152
- deferred.reject();
158
+ deferred.reject(new Error(`Timed out while waiting for notebook serializer for type ${type} to be registered`));
153
159
  }, timeoutDuration);
160
+
161
+ await Promise.all(this.willUseNotebookSerializerEmitter.fire(type));
162
+
154
163
  return deferred.promise;
155
164
  }
156
165
 
@@ -77,13 +77,12 @@ export class CellEditor extends React.Component<CellEditorProps, {}> {
77
77
  }));
78
78
  this.toDispose.push(this.editor.onDocumentContentChanged(e => {
79
79
  notebookModel.cellDirtyChanged(cell, true);
80
- cell.source = e.document.getText();
81
80
  }));
82
81
  }
83
82
  }
84
83
 
85
- protected assignRef = (component: HTMLDivElement) => {
86
- this.container = component;
84
+ protected setContainer(component: HTMLDivElement | null): void {
85
+ this.container = component ?? undefined;
87
86
  };
88
87
 
89
88
  protected handleResize = () => {
@@ -91,7 +90,10 @@ export class CellEditor extends React.Component<CellEditorProps, {}> {
91
90
  };
92
91
 
93
92
  override render(): React.ReactNode {
94
- return <div className='theia-notebook-cell-editor' onResize={this.handleResize} id={this.props.cell.uri.toString()} ref={this.assignRef}></div>;
95
- }
93
+ return <div className='theia-notebook-cell-editor' onResize={this.handleResize} id={this.props.cell.uri.toString()}
94
+ ref={container => this.setContainer(container)}>
95
+
96
+ </div>;
97
+ }
96
98
 
97
99
  }
@@ -47,7 +47,11 @@ export class NotebookCellListView extends React.Component<CellListProps, Noteboo
47
47
  super(props);
48
48
  this.state = { selectedCell: undefined, dragOverIndicator: undefined };
49
49
  this.toDispose.push(props.notebookModel.onDidAddOrRemoveCell(e => {
50
- this.setState({ selectedCell: undefined });
50
+ if (e.newCellIds && e.newCellIds.length > 0) {
51
+ this.setState({ ...this.state, selectedCell: this.props.notebookModel.cells.find(model => model.handle === e.newCellIds![e.newCellIds!.length - 1]) });
52
+ } else {
53
+ this.setState({ ...this.state, selectedCell: this.props.notebookModel.cells.find(cell => cell === this.state.selectedCell)});
54
+ }
51
55
  }));
52
56
  }
53
57
 
@@ -101,7 +105,8 @@ export class NotebookCellListView extends React.Component<CellListProps, Noteboo
101
105
 
102
106
  protected onDragStart(event: React.DragEvent<HTMLLIElement>, index: number): void {
103
107
  event.stopPropagation();
104
- event.dataTransfer.setData('text/notebook-cell-index', index.toString());
108
+ event.dataTransfer.setData('text/theia-notebook-cell-index', index.toString());
109
+ event.dataTransfer.setData('text/plain', this.props.notebookModel.cells[index].source);
105
110
  }
106
111
 
107
112
  protected onDragOver(event: React.DragEvent<HTMLLIElement>, cell: NotebookCellModel, position?: 'top' | 'bottom'): void {
@@ -112,7 +117,7 @@ export class NotebookCellListView extends React.Component<CellListProps, Noteboo
112
117
  }
113
118
 
114
119
  protected onDrop(event: React.DragEvent<HTMLLIElement>, dropElementIndex: number): void {
115
- const index = parseInt(event.dataTransfer.getData('text/notebook-cell-index'));
120
+ const index = parseInt(event.dataTransfer.getData('text/theia-notebook-cell-index'));
116
121
  const isTargetBelow = index < dropElementIndex;
117
122
  let newIdx = this.state.dragOverIndicator?.position === 'top' ? dropElementIndex : dropElementIndex + 1;
118
123
  newIdx = isTargetBelow ? newIdx - 1 : newIdx;
@@ -29,6 +29,7 @@ export interface NotebookCellToolbarItem {
29
29
  icon?: string;
30
30
  label?: string;
31
31
  onClick: (e: React.MouseEvent) => void;
32
+ contextKeys?: Set<string>
32
33
  }
33
34
 
34
35
  @injectable()
@@ -85,7 +86,8 @@ export class NotebookCellToolbarFactory {
85
86
  includeAnchorArg: false,
86
87
  args: [notebookModel, cell, output]
87
88
  }) :
88
- () => this.commandRegistry.executeCommand(menuNode.command!, notebookModel, cell, output)
89
+ () => this.commandRegistry.executeCommand(menuNode.command!, notebookModel, cell, output),
90
+ contextKeys: menuNode.when ? this.contextKeyService.parseKeys(menuNode.when) : undefined
89
91
  };
90
92
  }
91
93
  }
@@ -17,24 +17,27 @@ import * as React from '@theia/core/shared/react';
17
17
  import { ACTION_ITEM } from '@theia/core/lib/browser';
18
18
  import { NotebookCellToolbarItem } from './notebook-cell-toolbar-factory';
19
19
  import { DisposableCollection, Event } from '@theia/core';
20
+ import { ContextKeyChangeEvent } from '@theia/core/lib/browser/context-key-service';
20
21
 
21
22
  export interface NotebookCellToolbarProps {
22
23
  getMenuItems: () => NotebookCellToolbarItem[];
23
- onContextKeysChanged: Event<void>;
24
+ onContextKeysChanged: Event<ContextKeyChangeEvent>;
24
25
  }
25
26
 
26
27
  interface NotebookCellToolbarState {
27
28
  inlineItems: NotebookCellToolbarItem[];
28
29
  }
29
30
 
30
- abstract class NotebookCellActionItems extends React.Component<NotebookCellToolbarProps, NotebookCellToolbarState> {
31
+ abstract class NotebookCellActionBar extends React.Component<NotebookCellToolbarProps, NotebookCellToolbarState> {
31
32
 
32
33
  protected toDispose = new DisposableCollection();
33
34
 
34
35
  constructor(props: NotebookCellToolbarProps) {
35
36
  super(props);
36
37
  this.toDispose.push(props.onContextKeysChanged(e => {
37
- this.setState({ inlineItems: this.props.getMenuItems() });
38
+ if (this.props.getMenuItems().some(item => item.contextKeys ? e.affects(item.contextKeys) : false)) {
39
+ this.setState({ inlineItems: this.props.getMenuItems() });
40
+ }
38
41
  }));
39
42
  this.state = { inlineItems: this.props.getMenuItems() };
40
43
  }
@@ -49,7 +52,7 @@ abstract class NotebookCellActionItems extends React.Component<NotebookCellToolb
49
52
 
50
53
  }
51
54
 
52
- export class NotebookCellToolbar extends NotebookCellActionItems {
55
+ export class NotebookCellToolbar extends NotebookCellActionBar {
53
56
 
54
57
  override render(): React.ReactNode {
55
58
  return <div className='theia-notebook-cell-toolbar'>
@@ -59,7 +62,7 @@ export class NotebookCellToolbar extends NotebookCellActionItems {
59
62
 
60
63
  }
61
64
 
62
- export class NotebookCellSidebar extends NotebookCellActionItems {
65
+ export class NotebookCellSidebar extends NotebookCellActionBar {
63
66
 
64
67
  override render(): React.ReactNode {
65
68
  return <div className='theia-notebook-cell-sidebar'>
@@ -66,6 +66,15 @@ export class NotebookMainToolbar extends React.Component<NotebookMainToolbarProp
66
66
  this.setState({ selectedKernelLabel: props.notebookKernelService.getSelectedOrSuggestedKernel(props.notebookModel)?.label });
67
67
  }
68
68
  }));
69
+
70
+ // TODO maybe we need a mechanism to check for changes in the menu to update this toolbar
71
+ const contextKeys = new Set<string>();
72
+ this.getMenuItems().filter(item => item.when).forEach(item => props.contextKeyService.parseKeys(item.when!)?.forEach(key => contextKeys.add(key)));
73
+ props.contextKeyService.onDidChange(e => {
74
+ if (e.affects(contextKeys)) {
75
+ this.forceUpdate();
76
+ }
77
+ });
69
78
  }
70
79
 
71
80
  override componentWillUnmount(): void {
@@ -20,12 +20,14 @@
20
20
 
21
21
  import { Disposable, DisposableCollection, Emitter, Event, URI } from '@theia/core';
22
22
  import { inject, injectable, interfaces, postConstruct } from '@theia/core/shared/inversify';
23
+ import { ContextKeyChangeEvent } from '@theia/core/lib/browser/context-key-service';
23
24
  import { MonacoEditorModel } from '@theia/monaco/lib/browser/monaco-editor-model';
24
25
  import { MonacoTextModelService } from '@theia/monaco/lib/browser/monaco-text-model-service';
25
26
  import {
26
- CellInternalMetadataChangedEvent, CellKind, NotebookCellCollapseState, NotebookCellInternalMetadata,
27
- NotebookCellMetadata, NotebookCellOutputsSplice, CellOutput, CellData, NotebookCell, CellOutputItem
27
+ CellKind, NotebookCellCollapseState, NotebookCellInternalMetadata,
28
+ NotebookCellMetadata, CellOutput, CellData, CellOutputItem
28
29
  } from '../../common';
30
+ import { NotebookCellOutputsSplice } from '../notebook-types';
29
31
  import { NotebookCellOutputModel } from './notebook-cell-output-model';
30
32
 
31
33
  export const NotebookCellModelFactory = Symbol('NotebookModelFactory');
@@ -47,7 +49,28 @@ const NotebookCellContextManager = Symbol('NotebookCellContextManager');
47
49
  interface NotebookCellContextManager {
48
50
  updateCellContext(cell: NotebookCellModel, context: HTMLElement): void;
49
51
  dispose(): void;
50
- onDidChangeContext: Event<void>;
52
+ onDidChangeContext: Event<ContextKeyChangeEvent>;
53
+ }
54
+
55
+ export interface CellInternalMetadataChangedEvent {
56
+ readonly lastRunSuccessChanged?: boolean;
57
+ }
58
+
59
+ export interface NotebookCell {
60
+ readonly uri: URI;
61
+ handle: number;
62
+ language: string;
63
+ cellKind: CellKind;
64
+ outputs: CellOutput[];
65
+ metadata: NotebookCellMetadata;
66
+ internalMetadata: NotebookCellInternalMetadata;
67
+ text: string;
68
+ onDidChangeOutputs?: Event<NotebookCellOutputsSplice>;
69
+ onDidChangeOutputItems?: Event<CellOutput>;
70
+ onDidChangeLanguage: Event<string>;
71
+ onDidChangeMetadata: Event<void>;
72
+ onDidChangeInternalMetadata: Event<CellInternalMetadataChangedEvent>;
73
+
51
74
  }
52
75
 
53
76
  const NotebookCellModelProps = Symbol('NotebookModelProps');
@@ -144,6 +167,7 @@ export class NotebookCellModel implements NotebookCell, Disposable {
144
167
  }
145
168
  set source(source: string) {
146
169
  this.props.source = source;
170
+ this.textModel?.textEditorModel.setValue(source);
147
171
  }
148
172
  get language(): string {
149
173
  return this.props.language;
@@ -274,6 +298,9 @@ export class NotebookCellModel implements NotebookCell, Disposable {
274
298
 
275
299
  const ref = await this.textModelService.createModelReference(this.uri);
276
300
  this.textModel = ref.object;
301
+ this.textModel.onDidChangeContent(e => {
302
+ this.props.source = e.model.getText();
303
+ });
277
304
  return ref.object;
278
305
  }
279
306
  }
@@ -15,8 +15,8 @@
15
15
  // *****************************************************************************
16
16
 
17
17
  import { Disposable, Emitter } from '@theia/core';
18
- import { BinaryBuffer } from '@theia/core/lib/common/buffer';
19
18
  import { CellOutput, CellOutputItem, isTextStreamMime } from '../../common';
19
+ import { compressOutputItemStreams } from '../notebook-output-utils';
20
20
 
21
21
  export class NotebookCellOutputModel implements Disposable {
22
22
 
@@ -73,10 +73,10 @@ export class NotebookCellOutputModel implements Disposable {
73
73
  if (this.outputs.length > 1 && this.outputs.every(item => isTextStreamMime(item.mime))) {
74
74
  // Look for the mimes in the items, and keep track of their order.
75
75
  // Merge the streams into one output item, per mime type.
76
- const mimeOutputs = new Map<string, BinaryBuffer[]>();
76
+ const mimeOutputs = new Map<string, Uint8Array[]>();
77
77
  const mimeTypes: string[] = [];
78
78
  this.outputs.forEach(item => {
79
- let items: BinaryBuffer[];
79
+ let items: Uint8Array[];
80
80
  if (mimeOutputs.has(item.mime)) {
81
81
  items = mimeOutputs.get(item.mime)!;
82
82
  } else {
@@ -84,13 +84,14 @@ export class NotebookCellOutputModel implements Disposable {
84
84
  mimeOutputs.set(item.mime, items);
85
85
  mimeTypes.push(item.mime);
86
86
  }
87
- items.push(item.data);
87
+ items.push(item.data.buffer);
88
88
  });
89
89
  this.outputs.length = 0;
90
90
  mimeTypes.forEach(mime => {
91
+ const compressionResult = compressOutputItemStreams(mimeOutputs.get(mime)!);
91
92
  this.outputs.push({
92
93
  mime,
93
- data: BinaryBuffer.concat(mimeOutputs.get(mime)!)
94
+ data: compressionResult.data
94
95
  });
95
96
  });
96
97
  }