@theia/notebook 1.54.0 → 1.55.0-next.14

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 (65) hide show
  1. package/lib/browser/contributions/notebook-cell-actions-contribution.d.ts.map +1 -1
  2. package/lib/browser/contributions/notebook-cell-actions-contribution.js +5 -1
  3. package/lib/browser/contributions/notebook-cell-actions-contribution.js.map +1 -1
  4. package/lib/browser/contributions/notebook-status-bar-contribution.d.ts +7 -9
  5. package/lib/browser/contributions/notebook-status-bar-contribution.d.ts.map +1 -1
  6. package/lib/browser/contributions/notebook-status-bar-contribution.js +21 -33
  7. package/lib/browser/contributions/notebook-status-bar-contribution.js.map +1 -1
  8. package/lib/browser/notebook-editor-widget.d.ts +4 -0
  9. package/lib/browser/notebook-editor-widget.d.ts.map +1 -1
  10. package/lib/browser/notebook-editor-widget.js +26 -3
  11. package/lib/browser/notebook-editor-widget.js.map +1 -1
  12. package/lib/browser/notebook-frontend-module.d.ts.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/renderers/cell-output-webview.d.ts +17 -3
  16. package/lib/browser/renderers/cell-output-webview.d.ts.map +1 -1
  17. package/lib/browser/renderers/cell-output-webview.js +2 -1
  18. package/lib/browser/renderers/cell-output-webview.js.map +1 -1
  19. package/lib/browser/service/notebook-cell-editor-service.d.ts +3 -0
  20. package/lib/browser/service/notebook-cell-editor-service.d.ts.map +1 -1
  21. package/lib/browser/service/notebook-cell-editor-service.js +26 -2
  22. package/lib/browser/service/notebook-cell-editor-service.js.map +1 -1
  23. package/lib/browser/service/notebook-editor-widget-service.d.ts +4 -0
  24. package/lib/browser/service/notebook-editor-widget-service.d.ts.map +1 -1
  25. package/lib/browser/service/notebook-editor-widget-service.js +19 -0
  26. package/lib/browser/service/notebook-editor-widget-service.js.map +1 -1
  27. package/lib/browser/view/notebook-cell-list-view.d.ts +4 -1
  28. package/lib/browser/view/notebook-cell-list-view.d.ts.map +1 -1
  29. package/lib/browser/view/notebook-cell-list-view.js +36 -13
  30. package/lib/browser/view/notebook-cell-list-view.js.map +1 -1
  31. package/lib/browser/view/notebook-code-cell-view.d.ts +17 -9
  32. package/lib/browser/view/notebook-code-cell-view.d.ts.map +1 -1
  33. package/lib/browser/view/notebook-code-cell-view.js +53 -70
  34. package/lib/browser/view/notebook-code-cell-view.js.map +1 -1
  35. package/lib/browser/view/notebook-markdown-cell-view.d.ts +1 -0
  36. package/lib/browser/view/notebook-markdown-cell-view.d.ts.map +1 -1
  37. package/lib/browser/view/notebook-markdown-cell-view.js +9 -2
  38. package/lib/browser/view/notebook-markdown-cell-view.js.map +1 -1
  39. package/lib/browser/view-model/notebook-cell-model.d.ts +5 -0
  40. package/lib/browser/view-model/notebook-cell-model.d.ts.map +1 -1
  41. package/lib/browser/view-model/notebook-cell-model.js +10 -0
  42. package/lib/browser/view-model/notebook-cell-model.js.map +1 -1
  43. package/lib/browser/view-model/notebook-cell-output-model.d.ts +0 -3
  44. package/lib/browser/view-model/notebook-cell-output-model.d.ts.map +1 -1
  45. package/lib/browser/view-model/notebook-cell-output-model.js +0 -6
  46. package/lib/browser/view-model/notebook-cell-output-model.js.map +1 -1
  47. package/lib/browser/view-model/notebook-model.d.ts +2 -1
  48. package/lib/browser/view-model/notebook-model.d.ts.map +1 -1
  49. package/lib/browser/view-model/notebook-model.js +3 -0
  50. package/lib/browser/view-model/notebook-model.js.map +1 -1
  51. package/package.json +7 -7
  52. package/src/browser/contributions/notebook-cell-actions-contribution.ts +4 -1
  53. package/src/browser/contributions/notebook-status-bar-contribution.ts +23 -34
  54. package/src/browser/notebook-editor-widget.tsx +34 -9
  55. package/src/browser/notebook-frontend-module.ts +4 -2
  56. package/src/browser/renderers/cell-output-webview.ts +21 -3
  57. package/src/browser/service/notebook-cell-editor-service.ts +21 -3
  58. package/src/browser/service/notebook-editor-widget-service.ts +20 -0
  59. package/src/browser/style/index.css +35 -9
  60. package/src/browser/view/notebook-cell-list-view.tsx +44 -13
  61. package/src/browser/view/notebook-code-cell-view.tsx +78 -88
  62. package/src/browser/view/notebook-markdown-cell-view.tsx +10 -3
  63. package/src/browser/view-model/notebook-cell-model.ts +13 -0
  64. package/src/browser/view-model/notebook-cell-output-model.ts +0 -8
  65. package/src/browser/view-model/notebook-model.ts +5 -1
@@ -17,12 +17,11 @@
17
17
  import { inject, injectable } from '@theia/core/shared/inversify';
18
18
  import * as React from '@theia/core/shared/react';
19
19
  import { MonacoEditorServices } from '@theia/monaco/lib/browser/monaco-editor';
20
- import { CellOutputWebviewFactory, CellOutputWebview } from '../renderers/cell-output-webview';
21
20
  import { NotebookRendererRegistry } from '../notebook-renderer-registry';
22
21
  import { NotebookCellModel } from '../view-model/notebook-cell-model';
23
22
  import { NotebookModel } from '../view-model/notebook-model';
24
23
  import { CellEditor } from './notebook-cell-editor';
25
- import { CellRenderer } from './notebook-cell-list-view';
24
+ import { CellRenderer, observeCellHeight } from './notebook-cell-list-view';
26
25
  import { NotebookCellToolbarFactory } from './notebook-cell-toolbar-factory';
27
26
  import { NotebookCellActionContribution, NotebookCellCommands } from '../contributions/notebook-cell-actions-contribution';
28
27
  import { CellExecution, NotebookExecutionStateService } from '../service/notebook-execution-state-service';
@@ -36,6 +35,7 @@ import { NotebookOptionsService } from '../service/notebook-options';
36
35
  import { MarkdownRenderer } from '@theia/core/lib/browser/markdown-rendering/markdown-renderer';
37
36
  import { MarkdownString } from '@theia/monaco-editor-core/esm/vs/base/common/htmlContent';
38
37
  import { NotebookCellEditorService } from '../service/notebook-cell-editor-service';
38
+ import { CellOutputWebview } from '../renderers/cell-output-webview';
39
39
 
40
40
  @injectable()
41
41
  export class NotebookCodeCellRenderer implements CellRenderer {
@@ -45,9 +45,6 @@ export class NotebookCodeCellRenderer implements CellRenderer {
45
45
  @inject(NotebookRendererRegistry)
46
46
  protected readonly notebookRendererRegistry: NotebookRendererRegistry;
47
47
 
48
- @inject(CellOutputWebviewFactory)
49
- protected readonly cellOutputWebviewFactory: CellOutputWebviewFactory;
50
-
51
48
  @inject(NotebookCellToolbarFactory)
52
49
  protected readonly notebookCellToolbarFactory: NotebookCellToolbarFactory;
53
50
 
@@ -75,40 +72,39 @@ export class NotebookCodeCellRenderer implements CellRenderer {
75
72
  @inject(MarkdownRenderer)
76
73
  protected readonly markdownRenderer: MarkdownRenderer;
77
74
 
75
+ @inject(CellOutputWebview)
76
+ protected readonly outputWebview: CellOutputWebview;
77
+
78
78
  render(notebookModel: NotebookModel, cell: NotebookCellModel, handle: number): React.ReactNode {
79
- return <div>
80
- <div className='theia-notebook-cell-with-sidebar'>
81
- <div className='theia-notebook-cell-sidebar'>
82
- {this.notebookCellToolbarFactory.renderSidebar(NotebookCellActionContribution.CODE_CELL_SIDEBAR_MENU, cell, {
83
- contextMenuArgs: () => [cell], commandArgs: () => [notebookModel, cell]
84
- })
85
- }
86
- <CodeCellExecutionOrder cell={cell} />
87
- </div>
88
- <div className='theia-notebook-cell-editor-container'>
89
- <CellEditor notebookModel={notebookModel} cell={cell}
90
- monacoServices={this.monacoServices}
91
- notebookContextManager={this.notebookContextManager}
92
- notebookViewportService={this.notebookViewportService}
93
- notebookCellEditorService={this.notebookCellEditorService}
94
- fontInfo={this.notebookOptionsService.editorFontInfo} />
95
- <NotebookCodeCellStatus cell={cell} notebook={notebookModel}
96
- commandRegistry={this.commandRegistry}
97
- executionStateService={this.executionStateService}
98
- onClick={() => cell.requestFocusEditor()} />
99
- </div >
79
+ return <div className='theia-notebook-cell-with-sidebar' ref={ref => observeCellHeight(ref, cell)}>
80
+ <div className='theia-notebook-cell-editor-container'>
81
+ <CellEditor notebookModel={notebookModel} cell={cell}
82
+ monacoServices={this.monacoServices}
83
+ notebookContextManager={this.notebookContextManager}
84
+ notebookViewportService={this.notebookViewportService}
85
+ notebookCellEditorService={this.notebookCellEditorService}
86
+ fontInfo={this.notebookOptionsService.editorFontInfo} />
87
+ <NotebookCodeCellStatus cell={cell} notebook={notebookModel}
88
+ commandRegistry={this.commandRegistry}
89
+ executionStateService={this.executionStateService}
90
+ onClick={() => cell.requestFocusEditor()} />
100
91
  </div >
101
- <div className='theia-notebook-cell-with-sidebar'>
102
- <NotebookCodeCellOutputs cell={cell} notebook={notebookModel} outputWebviewFactory={this.cellOutputWebviewFactory}
103
- renderSidebar={() =>
104
- this.notebookCellToolbarFactory.renderSidebar(NotebookCellActionContribution.OUTPUT_SIDEBAR_MENU, cell, {
105
- contextMenuArgs: () => [notebookModel, cell, cell.outputs[0]]
106
- })
107
- } />
108
- </div>
109
92
  </div >;
110
93
  }
111
94
 
95
+ renderSidebar(notebookModel: NotebookModel, cell: NotebookCellModel): React.ReactNode {
96
+ return <div>
97
+ <NotebookCodeCellSidebar cell={cell} notebook={notebookModel} notebookCellToolbarFactory={this.notebookCellToolbarFactory} />
98
+ <NotebookCodeCellOutputs cell={cell} notebook={notebookModel} outputWebview={this.outputWebview}
99
+ renderSidebar={() =>
100
+ this.notebookCellToolbarFactory.renderSidebar(NotebookCellActionContribution.OUTPUT_SIDEBAR_MENU, cell, {
101
+ contextMenuArgs: () => [notebookModel, cell, cell.outputs[0]]
102
+ })
103
+ } />
104
+ </div>;
105
+
106
+ }
107
+
112
108
  renderDragImage(cell: NotebookCellModel): HTMLElement {
113
109
  const dragImage = document.createElement('div');
114
110
  dragImage.className = 'theia-notebook-drag-image';
@@ -151,6 +147,37 @@ export class NotebookCodeCellRenderer implements CellRenderer {
151
147
 
152
148
  }
153
149
 
150
+ export interface NotebookCodeCellSidebarProps {
151
+ cell: NotebookCellModel;
152
+ notebook: NotebookModel;
153
+ notebookCellToolbarFactory: NotebookCellToolbarFactory
154
+ }
155
+
156
+ export class NotebookCodeCellSidebar extends React.Component<NotebookCodeCellSidebarProps> {
157
+
158
+ protected toDispose = new DisposableCollection();
159
+
160
+ constructor(props: NotebookCodeCellSidebarProps) {
161
+ super(props);
162
+
163
+ this.toDispose.push(props.cell.onDidCellHeightChange(() => this.forceUpdate()));
164
+ }
165
+
166
+ override componentWillUnmount(): void {
167
+ this.toDispose.dispose();
168
+ }
169
+
170
+ override render(): React.ReactNode {
171
+ return <div className='theia-notebook-cell-sidebar-actions' style={{ height: `${this.props.cell.cellHeight}px` }}>
172
+ {this.props.notebookCellToolbarFactory.renderSidebar(NotebookCellActionContribution.CODE_CELL_SIDEBAR_MENU, this.props.cell, {
173
+ contextMenuArgs: () => [this.props.cell], commandArgs: () => [this.props.notebook, this.props.cell]
174
+ })
175
+ }
176
+ <CodeCellExecutionOrder cell={this.props.cell} />
177
+ </div>;
178
+ }
179
+ }
180
+
154
181
  export interface NotebookCodeCellStatusProps {
155
182
  notebook: NotebookModel;
156
183
  cell: NotebookCellModel;
@@ -260,79 +287,42 @@ export class NotebookCodeCellStatus extends React.Component<NotebookCodeCellStat
260
287
  interface NotebookCellOutputProps {
261
288
  cell: NotebookCellModel;
262
289
  notebook: NotebookModel;
263
- outputWebviewFactory: CellOutputWebviewFactory;
290
+ outputWebview: CellOutputWebview;
264
291
  renderSidebar: () => React.ReactNode;
265
292
  }
266
293
 
267
294
  export class NotebookCodeCellOutputs extends React.Component<NotebookCellOutputProps> {
268
295
 
269
- protected outputsWebview: CellOutputWebview | undefined;
270
- protected outputsWebviewPromise: Promise<CellOutputWebview> | undefined;
271
-
272
296
  protected toDispose = new DisposableCollection();
273
297
 
274
- constructor(props: NotebookCellOutputProps) {
275
- super(props);
276
- }
298
+ protected outputHeight: number = 0;
277
299
 
278
300
  override async componentDidMount(): Promise<void> {
279
- const { cell, notebook, outputWebviewFactory } = this.props;
280
- this.toDispose.push(cell.onDidChangeOutputs(() => this.updateOutputs()));
281
- this.toDispose.push(cell.onDidChangeOutputVisibility(visible => {
282
- if (!visible && this.outputsWebview) {
283
- this.outputsWebview?.dispose();
284
- this.outputsWebview = undefined;
285
- this.outputsWebviewPromise = undefined;
301
+ const { cell } = this.props;
302
+ this.toDispose.push(cell.onDidChangeOutputs(() => this.forceUpdate()));
303
+ this.toDispose.push(this.props.cell.onDidChangeOutputVisibility(() => this.forceUpdate()));
304
+ this.toDispose.push(this.props.outputWebview.onDidRenderOutput(event => {
305
+ if (event.cellHandle === this.props.cell.handle) {
306
+ this.outputHeight = event.outputHeight;
286
307
  this.forceUpdate();
287
- } else {
288
- this.updateOutputs();
289
308
  }
290
309
  }));
291
- if (cell.outputs.length > 0) {
292
- this.outputsWebviewPromise = outputWebviewFactory(cell, notebook).then(webview => {
293
- this.outputsWebview = webview;
294
- this.forceUpdate();
295
- return webview;
296
- });
297
- }
298
310
  }
299
311
 
300
- protected async updateOutputs(): Promise<void> {
301
- const { cell, notebook, outputWebviewFactory } = this.props;
302
- if (!this.outputsWebviewPromise && cell.outputs.length > 0) {
303
- this.outputsWebviewPromise = outputWebviewFactory(cell, notebook).then(webview => {
304
- this.outputsWebview = webview;
305
- this.forceUpdate();
306
- return webview;
307
- });
308
- this.forceUpdate();
309
- } else if (this.outputsWebviewPromise && cell.outputs.length === 0 && cell.internalMetadata.runEndTime) {
310
- (await this.outputsWebviewPromise).dispose();
311
- this.outputsWebview = undefined;
312
- this.outputsWebviewPromise = undefined;
313
- this.forceUpdate();
314
- }
315
- }
316
-
317
- override async componentDidUpdate(): Promise<void> {
318
- if (!(await this.outputsWebviewPromise)?.isAttached()) {
319
- (await this.outputsWebviewPromise)?.attachWebview();
320
- }
321
- }
322
-
323
- override async componentWillUnmount(): Promise<void> {
312
+ override componentWillUnmount(): void {
324
313
  this.toDispose.dispose();
325
- (await this.outputsWebviewPromise)?.dispose();
326
314
  }
327
315
 
328
316
  override render(): React.ReactNode {
329
- return this.outputsWebview && this.props.cell.outputVisible ?
330
- <>
317
+ if (!this.props.cell.outputs?.length) {
318
+ return <></>;
319
+ }
320
+ if (this.props.cell.outputVisible) {
321
+ return <div style={{ minHeight: this.outputHeight }}>
331
322
  {this.props.renderSidebar()}
332
- {this.outputsWebview.render()}
333
- </> :
334
- this.props.cell.outputs?.length ? <i className='theia-notebook-collapsed-output'>{nls.localizeByDefault('Outputs are collapsed')}</i> : <></>;
335
-
323
+ </div>;
324
+ }
325
+ return <div className='theia-notebook-collapsed-output-container'><i className='theia-notebook-collapsed-output'>{nls.localizeByDefault('Outputs are collapsed')}</i></div>;
336
326
  }
337
327
 
338
328
  }
@@ -18,7 +18,7 @@ import * as React from '@theia/core/shared/react';
18
18
  import { MarkdownRenderer } from '@theia/core/lib/browser/markdown-rendering/markdown-renderer';
19
19
  import { MarkdownStringImpl } from '@theia/core/lib/common/markdown-rendering/markdown-string';
20
20
  import { NotebookModel } from '../view-model/notebook-model';
21
- import { CellRenderer } from './notebook-cell-list-view';
21
+ import { CellRenderer, observeCellHeight } from './notebook-cell-list-view';
22
22
  import { NotebookCellModel } from '../view-model/notebook-cell-model';
23
23
  import { CellEditor } from './notebook-cell-editor';
24
24
  import { inject, injectable } from '@theia/core/shared/inversify';
@@ -63,6 +63,10 @@ export class NotebookMarkdownCellRenderer implements CellRenderer {
63
63
  notebookCellEditorService={this.notebookCellEditorService} />;
64
64
  }
65
65
 
66
+ renderSidebar(notebookModel: NotebookModel, cell: NotebookCellModel): React.ReactNode {
67
+ return <div className='theia-notebook-markdown-sidebar'></div>;
68
+ }
69
+
66
70
  renderDragImage(cell: NotebookCellModel): HTMLElement {
67
71
  const dragImage = document.createElement('div');
68
72
  dragImage.style.width = this.notebookContextManager.context?.clientWidth + 'px';
@@ -135,7 +139,7 @@ function MarkdownCell({
135
139
  }
136
140
 
137
141
  return editMode ?
138
- (<div className='theia-notebook-markdown-editor-container' key="code">
142
+ (<div className='theia-notebook-markdown-editor-container' key="code" ref={ref => observeCellHeight(ref, cell)}>
139
143
  <CellEditor notebookModel={notebookModel} cell={cell}
140
144
  monacoServices={monacoServices}
141
145
  notebookContextManager={notebookContextManager}
@@ -147,7 +151,10 @@ function MarkdownCell({
147
151
  </div >) :
148
152
  (<div className='theia-notebook-markdown-content' key="markdown"
149
153
  onDoubleClick={() => cell.requestEdit()}
150
- ref={node => node?.replaceChildren(...markdownContent)}
154
+ ref={node => {
155
+ node?.replaceChildren(...markdownContent);
156
+ observeCellHeight(node, cell);
157
+ }}
151
158
  />);
152
159
  }
153
160
 
@@ -129,6 +129,9 @@ export class NotebookCellModel implements NotebookCell, Disposable {
129
129
  protected onDidRequestCenterEditorEmitter = new Emitter<void>();
130
130
  readonly onDidRequestCenterEditor = this.onDidRequestCenterEditorEmitter.event;
131
131
 
132
+ protected onDidCellHeightChangeEmitter = new Emitter<number>();
133
+ readonly onDidCellHeightChange = this.onDidCellHeightChangeEmitter.event;
134
+
132
135
  @inject(NotebookCellModelProps)
133
136
  protected readonly props: NotebookCellModelProps;
134
137
 
@@ -251,6 +254,16 @@ export class NotebookCellModel implements NotebookCell, Disposable {
251
254
  }
252
255
  }
253
256
 
257
+ protected _cellheight: number = 0;
258
+ get cellHeight(): number {
259
+ return this._cellheight;
260
+ }
261
+
262
+ set cellHeight(height: number) {
263
+ this.onDidCellHeightChangeEmitter.fire(height);
264
+ this._cellheight = height;
265
+ }
266
+
254
267
  @postConstruct()
255
268
  protected init(): void {
256
269
  this._outputs = this.props.outputs.map(op => new NotebookCellOutputModel(op));
@@ -23,9 +23,6 @@ export class NotebookCellOutputModel implements Disposable {
23
23
  private didChangeDataEmitter = new Emitter<void>();
24
24
  readonly onDidChangeData = this.didChangeDataEmitter.event;
25
25
 
26
- private requestOutputPresentationChangeEmitter = new Emitter<void>();
27
- readonly onRequestOutputPresentationChange = this.requestOutputPresentationChangeEmitter.event;
28
-
29
26
  get outputId(): string {
30
27
  return this.rawOutput.outputId;
31
28
  }
@@ -54,11 +51,6 @@ export class NotebookCellOutputModel implements Disposable {
54
51
 
55
52
  dispose(): void {
56
53
  this.didChangeDataEmitter.dispose();
57
- this.requestOutputPresentationChangeEmitter.dispose();
58
- }
59
-
60
- requestOutputPresentationUpdate(): void {
61
- this.requestOutputPresentationChangeEmitter.fire();
62
54
  }
63
55
 
64
56
  getData(): CellOutput {
@@ -509,10 +509,14 @@ export class NotebookModel implements Saveable, Disposable {
509
509
  return true;
510
510
  }
511
511
 
512
- protected getCellIndexByHandle(handle: number): number {
512
+ getCellIndexByHandle(handle: number): number {
513
513
  return this.cells.findIndex(c => c.handle === handle);
514
514
  }
515
515
 
516
+ getCellByHandle(handle: number): NotebookCellModel | undefined {
517
+ return this.cells.find(c => c.handle === handle);
518
+ }
519
+
516
520
  protected isCellMetadataChanged(a: NotebookCellMetadata, b: NotebookCellMetadata): boolean {
517
521
  const keys = new Set<keyof NotebookCellMetadata>([...Object.keys(a || {}), ...Object.keys(b || {})]);
518
522
  for (const key of keys) {