@theia/notebook 1.48.2 → 1.49.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.
- package/lib/browser/contributions/notebook-actions-contribution.d.ts +7 -1
- package/lib/browser/contributions/notebook-actions-contribution.d.ts.map +1 -1
- package/lib/browser/contributions/notebook-actions-contribution.js +81 -7
- package/lib/browser/contributions/notebook-actions-contribution.js.map +1 -1
- package/lib/browser/contributions/notebook-cell-actions-contribution.d.ts +5 -0
- package/lib/browser/contributions/notebook-cell-actions-contribution.d.ts.map +1 -1
- package/lib/browser/contributions/notebook-cell-actions-contribution.js +86 -9
- package/lib/browser/contributions/notebook-cell-actions-contribution.js.map +1 -1
- package/lib/browser/contributions/notebook-label-provider-contribution.d.ts +16 -0
- package/lib/browser/contributions/notebook-label-provider-contribution.d.ts.map +1 -0
- package/lib/browser/contributions/notebook-label-provider-contribution.js +65 -0
- package/lib/browser/contributions/notebook-label-provider-contribution.js.map +1 -0
- package/lib/browser/contributions/notebook-outline-contribution.d.ts +30 -0
- package/lib/browser/contributions/notebook-outline-contribution.d.ts.map +1 -0
- package/lib/browser/contributions/notebook-outline-contribution.js +109 -0
- package/lib/browser/contributions/notebook-outline-contribution.js.map +1 -0
- package/lib/browser/contributions/notebook-output-action-contribution.d.ts +16 -0
- package/lib/browser/contributions/notebook-output-action-contribution.d.ts.map +1 -0
- package/lib/browser/contributions/notebook-output-action-contribution.js +85 -0
- package/lib/browser/contributions/notebook-output-action-contribution.js.map +1 -0
- package/lib/browser/contributions/notebook-preferences.d.ts +4 -0
- package/lib/browser/contributions/notebook-preferences.d.ts.map +1 -0
- package/lib/browser/contributions/notebook-preferences.js +31 -0
- package/lib/browser/contributions/notebook-preferences.js.map +1 -0
- package/lib/browser/notebook-cell-resource-resolver.d.ts +4 -0
- package/lib/browser/notebook-cell-resource-resolver.d.ts.map +1 -1
- package/lib/browser/notebook-cell-resource-resolver.js +35 -2
- package/lib/browser/notebook-cell-resource-resolver.js.map +1 -1
- package/lib/browser/notebook-editor-widget-factory.d.ts +1 -0
- package/lib/browser/notebook-editor-widget-factory.d.ts.map +1 -1
- package/lib/browser/notebook-editor-widget-factory.js +17 -3
- package/lib/browser/notebook-editor-widget-factory.js.map +1 -1
- package/lib/browser/notebook-editor-widget.d.ts +5 -1
- package/lib/browser/notebook-editor-widget.d.ts.map +1 -1
- package/lib/browser/notebook-editor-widget.js +20 -2
- package/lib/browser/notebook-editor-widget.js.map +1 -1
- package/lib/browser/notebook-frontend-module.d.ts.map +1 -1
- package/lib/browser/notebook-frontend-module.js +15 -2
- package/lib/browser/notebook-frontend-module.js.map +1 -1
- package/lib/browser/notebook-open-handler.d.ts +14 -9
- package/lib/browser/notebook-open-handler.d.ts.map +1 -1
- package/lib/browser/notebook-open-handler.js +38 -16
- package/lib/browser/notebook-open-handler.js.map +1 -1
- package/lib/browser/notebook-type-registry.d.ts +5 -1
- package/lib/browser/notebook-type-registry.d.ts.map +1 -1
- package/lib/browser/notebook-type-registry.js +27 -7
- package/lib/browser/notebook-type-registry.js.map +1 -1
- package/lib/browser/notebook-types.d.ts +2 -0
- package/lib/browser/notebook-types.d.ts.map +1 -1
- package/lib/browser/notebook-types.js.map +1 -1
- package/lib/browser/service/notebook-clipboard-service.d.ts +10 -0
- package/lib/browser/service/notebook-clipboard-service.d.ts.map +1 -0
- package/lib/browser/service/notebook-clipboard-service.js +42 -0
- package/lib/browser/service/notebook-clipboard-service.js.map +1 -0
- package/lib/browser/service/notebook-context-manager.d.ts +4 -1
- package/lib/browser/service/notebook-context-manager.d.ts.map +1 -1
- package/lib/browser/service/notebook-context-manager.js +33 -12
- package/lib/browser/service/notebook-context-manager.js.map +1 -1
- package/lib/browser/service/notebook-service.d.ts.map +1 -1
- package/lib/browser/service/notebook-service.js +4 -0
- package/lib/browser/service/notebook-service.js.map +1 -1
- package/lib/browser/view/notebook-cell-editor.d.ts.map +1 -1
- package/lib/browser/view/notebook-cell-editor.js +11 -2
- package/lib/browser/view/notebook-cell-editor.js.map +1 -1
- package/lib/browser/view/notebook-cell-list-view.d.ts.map +1 -1
- package/lib/browser/view/notebook-cell-list-view.js +4 -2
- package/lib/browser/view/notebook-cell-list-view.js.map +1 -1
- package/lib/browser/view/notebook-cell-toolbar-factory.d.ts +6 -4
- package/lib/browser/view/notebook-cell-toolbar-factory.d.ts.map +1 -1
- package/lib/browser/view/notebook-cell-toolbar-factory.js +21 -18
- package/lib/browser/view/notebook-cell-toolbar-factory.js.map +1 -1
- package/lib/browser/view/notebook-cell-toolbar.d.ts.map +1 -1
- package/lib/browser/view/notebook-cell-toolbar.js +3 -2
- package/lib/browser/view/notebook-cell-toolbar.js.map +1 -1
- package/lib/browser/view/notebook-code-cell-view.d.ts +5 -1
- package/lib/browser/view/notebook-code-cell-view.d.ts.map +1 -1
- package/lib/browser/view/notebook-code-cell-view.js +45 -17
- package/lib/browser/view/notebook-code-cell-view.js.map +1 -1
- package/lib/browser/view/notebook-main-toolbar.d.ts +5 -3
- package/lib/browser/view/notebook-main-toolbar.d.ts.map +1 -1
- package/lib/browser/view/notebook-main-toolbar.js +17 -9
- package/lib/browser/view/notebook-main-toolbar.js.map +1 -1
- package/lib/browser/view/notebook-markdown-cell-view.js +11 -8
- package/lib/browser/view/notebook-markdown-cell-view.js.map +1 -1
- package/lib/browser/view-model/notebook-cell-model.d.ts +20 -0
- package/lib/browser/view-model/notebook-cell-model.d.ts.map +1 -1
- package/lib/browser/view-model/notebook-cell-model.js +61 -2
- package/lib/browser/view-model/notebook-cell-model.js.map +1 -1
- package/lib/browser/view-model/notebook-model.d.ts +4 -2
- package/lib/browser/view-model/notebook-model.d.ts.map +1 -1
- package/lib/browser/view-model/notebook-model.js +25 -14
- package/lib/browser/view-model/notebook-model.js.map +1 -1
- package/lib/common/notebook-common.d.ts +7 -1
- package/lib/common/notebook-common.d.ts.map +1 -1
- package/lib/common/notebook-common.js +28 -4
- package/lib/common/notebook-common.js.map +1 -1
- package/package.json +9 -7
- package/src/browser/contributions/notebook-actions-contribution.ts +90 -9
- package/src/browser/contributions/notebook-cell-actions-contribution.ts +88 -11
- package/src/browser/contributions/notebook-label-provider-contribution.ts +63 -0
- package/src/browser/contributions/notebook-outline-contribution.ts +112 -0
- package/src/browser/contributions/notebook-output-action-contribution.ts +82 -0
- package/src/browser/contributions/notebook-preferences.ts +31 -0
- package/src/browser/notebook-cell-resource-resolver.ts +39 -1
- package/src/browser/notebook-editor-widget-factory.ts +18 -5
- package/src/browser/notebook-editor-widget.tsx +20 -2
- package/src/browser/notebook-frontend-module.ts +20 -4
- package/src/browser/notebook-open-handler.ts +48 -20
- package/src/browser/notebook-type-registry.ts +26 -6
- package/src/browser/notebook-types.ts +2 -0
- package/src/browser/service/notebook-clipboard-service.ts +43 -0
- package/src/browser/service/notebook-context-manager.ts +36 -10
- package/src/browser/service/notebook-service.ts +4 -0
- package/src/browser/style/index.css +19 -4
- package/src/browser/view/notebook-cell-editor.tsx +12 -2
- package/src/browser/view/notebook-cell-list-view.tsx +5 -2
- package/src/browser/view/notebook-cell-toolbar-factory.tsx +17 -15
- package/src/browser/view/notebook-cell-toolbar.tsx +3 -2
- package/src/browser/view/notebook-code-cell-view.tsx +51 -18
- package/src/browser/view/notebook-main-toolbar.tsx +20 -11
- package/src/browser/view/notebook-markdown-cell-view.tsx +12 -7
- package/src/browser/view-model/notebook-cell-model.ts +70 -2
- package/src/browser/view-model/notebook-model.ts +29 -16
- package/src/common/notebook-common.ts +29 -4
|
@@ -13,22 +13,42 @@
|
|
|
13
13
|
//
|
|
14
14
|
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
15
15
|
// *****************************************************************************
|
|
16
|
-
|
|
17
|
-
import {
|
|
16
|
+
|
|
17
|
+
import { Disposable, DisposableCollection } from '@theia/core';
|
|
18
|
+
import { inject, injectable } from '@theia/core/shared/inversify';
|
|
19
|
+
import { OpenWithService } from '@theia/core/lib/browser';
|
|
18
20
|
import { NotebookTypeDescriptor } from '../common/notebook-protocol';
|
|
21
|
+
import { NotebookOpenHandler } from './notebook-open-handler';
|
|
19
22
|
|
|
20
23
|
@injectable()
|
|
21
24
|
export class NotebookTypeRegistry {
|
|
25
|
+
|
|
26
|
+
@inject(OpenWithService)
|
|
27
|
+
protected readonly openWithService: OpenWithService;
|
|
28
|
+
|
|
29
|
+
@inject(NotebookOpenHandler)
|
|
30
|
+
protected readonly notebookOpenHandler: NotebookOpenHandler;
|
|
31
|
+
|
|
22
32
|
private readonly _notebookTypes: NotebookTypeDescriptor[] = [];
|
|
23
33
|
|
|
24
34
|
get notebookTypes(): readonly NotebookTypeDescriptor[] {
|
|
25
35
|
return this._notebookTypes;
|
|
26
36
|
}
|
|
27
37
|
|
|
28
|
-
registerNotebookType(type: NotebookTypeDescriptor): Disposable {
|
|
29
|
-
|
|
30
|
-
|
|
38
|
+
registerNotebookType(type: NotebookTypeDescriptor, providerName: string): Disposable {
|
|
39
|
+
const toDispose = new DisposableCollection();
|
|
40
|
+
toDispose.push(Disposable.create(() => {
|
|
31
41
|
this._notebookTypes.splice(this._notebookTypes.indexOf(type), 1);
|
|
32
|
-
});
|
|
42
|
+
}));
|
|
43
|
+
this._notebookTypes.push(type);
|
|
44
|
+
toDispose.push(this.notebookOpenHandler.registerNotebookType(type));
|
|
45
|
+
toDispose.push(this.openWithService.registerHandler({
|
|
46
|
+
id: type.type,
|
|
47
|
+
label: type.displayName,
|
|
48
|
+
providerName,
|
|
49
|
+
canHandle: uri => this.notebookOpenHandler.canHandleType(uri, type),
|
|
50
|
+
open: uri => this.notebookOpenHandler.open(uri, { notebookType: type.type })
|
|
51
|
+
}));
|
|
52
|
+
return toDispose;
|
|
33
53
|
}
|
|
34
54
|
}
|
|
@@ -111,6 +111,7 @@ export interface CellOutputEdit {
|
|
|
111
111
|
editType: CellEditType.Output;
|
|
112
112
|
index: number;
|
|
113
113
|
outputs: CellOutput[];
|
|
114
|
+
deleteCount?: number;
|
|
114
115
|
append?: boolean;
|
|
115
116
|
}
|
|
116
117
|
|
|
@@ -118,6 +119,7 @@ export interface CellOutputEditByHandle {
|
|
|
118
119
|
editType: CellEditType.Output;
|
|
119
120
|
handle: number;
|
|
120
121
|
outputs: CellOutput[];
|
|
122
|
+
deleteCount?: number;
|
|
121
123
|
append?: boolean;
|
|
122
124
|
}
|
|
123
125
|
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
// *****************************************************************************
|
|
2
|
+
// Copyright (C) 2024 Typefox and others.
|
|
3
|
+
//
|
|
4
|
+
// This program and the accompanying materials are made available under the
|
|
5
|
+
// terms of the Eclipse Public License v. 2.0 which is available at
|
|
6
|
+
// http://www.eclipse.org/legal/epl-2.0.
|
|
7
|
+
//
|
|
8
|
+
// This Source Code may also be made available under the following Secondary
|
|
9
|
+
// Licenses when the conditions for such availability set forth in the Eclipse
|
|
10
|
+
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
11
|
+
// with the GNU Classpath Exception which is available at
|
|
12
|
+
// https://www.gnu.org/software/classpath/license.html.
|
|
13
|
+
//
|
|
14
|
+
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
15
|
+
// *****************************************************************************
|
|
16
|
+
|
|
17
|
+
import { inject, injectable } from '@theia/core/shared/inversify';
|
|
18
|
+
import { ClipboardService } from '@theia/core/lib/browser/clipboard-service';
|
|
19
|
+
import { NotebookCellModel } from '../view-model/notebook-cell-model';
|
|
20
|
+
import { environment } from '@theia/core';
|
|
21
|
+
import { CellData } from '../../common';
|
|
22
|
+
|
|
23
|
+
@injectable()
|
|
24
|
+
export class NotebookClipboardService {
|
|
25
|
+
|
|
26
|
+
protected copiedCell: CellData | undefined;
|
|
27
|
+
|
|
28
|
+
@inject(ClipboardService)
|
|
29
|
+
protected readonly clipboardService: ClipboardService;
|
|
30
|
+
|
|
31
|
+
copyCell(cell: NotebookCellModel): void {
|
|
32
|
+
this.copiedCell = cell.getData();
|
|
33
|
+
|
|
34
|
+
if (environment.electron.is()) {
|
|
35
|
+
this.clipboardService.writeText(cell.text);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
getCell(): CellData | undefined {
|
|
40
|
+
return this.copiedCell;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
}
|
|
@@ -15,19 +15,19 @@
|
|
|
15
15
|
// *****************************************************************************
|
|
16
16
|
|
|
17
17
|
import { inject, injectable } from '@theia/core/shared/inversify';
|
|
18
|
-
import { ContextKeyChangeEvent, ContextKeyService, ScopedValueStore } from '@theia/core/lib/browser/context-key-service';
|
|
18
|
+
import { ContextKeyChangeEvent, ContextKeyService, ContextMatcher, ScopedValueStore } from '@theia/core/lib/browser/context-key-service';
|
|
19
19
|
import { DisposableCollection, Emitter } from '@theia/core';
|
|
20
20
|
import { NotebookKernelService } from './notebook-kernel-service';
|
|
21
21
|
import {
|
|
22
22
|
NOTEBOOK_CELL_EDITABLE,
|
|
23
23
|
NOTEBOOK_CELL_EXECUTING, NOTEBOOK_CELL_EXECUTION_STATE,
|
|
24
24
|
NOTEBOOK_CELL_FOCUSED, NOTEBOOK_CELL_MARKDOWN_EDIT_MODE,
|
|
25
|
-
NOTEBOOK_CELL_TYPE, NOTEBOOK_KERNEL, NOTEBOOK_KERNEL_SELECTED,
|
|
25
|
+
NOTEBOOK_CELL_TYPE, NOTEBOOK_HAS_OUTPUTS, NOTEBOOK_KERNEL, NOTEBOOK_KERNEL_SELECTED,
|
|
26
26
|
NOTEBOOK_VIEW_TYPE
|
|
27
27
|
} from '../contributions/notebook-context-keys';
|
|
28
28
|
import { NotebookEditorWidget } from '../notebook-editor-widget';
|
|
29
29
|
import { NotebookCellModel } from '../view-model/notebook-cell-model';
|
|
30
|
-
import { CellKind } from '../../common';
|
|
30
|
+
import { CellKind, NotebookCellsChangeType } from '../../common';
|
|
31
31
|
import { NotebookExecutionStateService } from './notebook-execution-state-service';
|
|
32
32
|
|
|
33
33
|
@injectable()
|
|
@@ -53,6 +53,8 @@ export class NotebookContextManager {
|
|
|
53
53
|
return this._context;
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
+
protected cellContexts: Map<number, Record<string, unknown>> = new Map();
|
|
57
|
+
|
|
56
58
|
init(widget: NotebookEditorWidget): void {
|
|
57
59
|
this._context = widget.node;
|
|
58
60
|
this.scopedStore = this.contextKeyService.createScoped(widget.node);
|
|
@@ -73,6 +75,15 @@ export class NotebookContextManager {
|
|
|
73
75
|
}
|
|
74
76
|
}));
|
|
75
77
|
|
|
78
|
+
widget.model?.onDidChangeContent(events => {
|
|
79
|
+
if (events.some(e => e.kind === NotebookCellsChangeType.ModelChange || e.kind === NotebookCellsChangeType.Output)) {
|
|
80
|
+
this.scopedStore.setContext(NOTEBOOK_HAS_OUTPUTS, widget.model?.cells.some(cell => cell.outputs.length > 0));
|
|
81
|
+
this.onDidChangeContextEmitter.fire(this.createContextKeyChangedEvent([NOTEBOOK_HAS_OUTPUTS]));
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
this.scopedStore.setContext(NOTEBOOK_HAS_OUTPUTS, !!widget.model?.cells.find(cell => cell.outputs.length > 0));
|
|
86
|
+
|
|
76
87
|
// Cell Selection realted keys
|
|
77
88
|
this.scopedStore.setContext(NOTEBOOK_CELL_FOCUSED, !!widget.model?.selectedCell);
|
|
78
89
|
widget.model?.onDidChangeSelectedCell(e => {
|
|
@@ -80,6 +91,14 @@ export class NotebookContextManager {
|
|
|
80
91
|
this.onDidChangeContextEmitter.fire(this.createContextKeyChangedEvent([NOTEBOOK_CELL_FOCUSED]));
|
|
81
92
|
});
|
|
82
93
|
|
|
94
|
+
this.toDispose.push(this.executionStateService.onDidChangeExecution(e => {
|
|
95
|
+
if (e.notebook.toString() === widget.model?.uri.toString()) {
|
|
96
|
+
this.setCellContext(e.cellHandle, NOTEBOOK_CELL_EXECUTING, !!e.changed);
|
|
97
|
+
this.setCellContext(e.cellHandle, NOTEBOOK_CELL_EXECUTION_STATE, e.changed?.state ?? 'idle');
|
|
98
|
+
this.onDidChangeContextEmitter.fire(this.createContextKeyChangedEvent([NOTEBOOK_CELL_EXECUTING, NOTEBOOK_CELL_EXECUTION_STATE]));
|
|
99
|
+
}
|
|
100
|
+
}));
|
|
101
|
+
|
|
83
102
|
widget.model?.onDidChangeSelectedCell(e => this.selectedCellChanged(e));
|
|
84
103
|
|
|
85
104
|
this.onDidChangeContextEmitter.fire(this.createContextKeyChangedEvent([NOTEBOOK_VIEW_TYPE, NOTEBOOK_KERNEL_SELECTED, NOTEBOOK_KERNEL]));
|
|
@@ -100,19 +119,26 @@ export class NotebookContextManager {
|
|
|
100
119
|
this.scopedStore.setContext(NOTEBOOK_CELL_EDITABLE, cell.cellKind === CellKind.Markup && !cellEdit);
|
|
101
120
|
this.onDidChangeContextEmitter.fire(this.createContextKeyChangedEvent([NOTEBOOK_CELL_MARKDOWN_EDIT_MODE]));
|
|
102
121
|
}));
|
|
103
|
-
this.cellDisposables.push(this.executionStateService.onDidChangeExecution(e => {
|
|
104
|
-
if (cell && e.affectsCell(cell.uri)) {
|
|
105
|
-
this.scopedStore.setContext(NOTEBOOK_CELL_EXECUTING, !!e.changed);
|
|
106
|
-
this.scopedStore.setContext(NOTEBOOK_CELL_EXECUTION_STATE, e.changed?.state ?? 'idle');
|
|
107
|
-
this.onDidChangeContextEmitter.fire(this.createContextKeyChangedEvent([NOTEBOOK_CELL_EXECUTING, NOTEBOOK_CELL_EXECUTION_STATE]));
|
|
108
|
-
}
|
|
109
|
-
}));
|
|
110
122
|
}
|
|
111
123
|
|
|
112
124
|
this.onDidChangeContextEmitter.fire(this.createContextKeyChangedEvent([NOTEBOOK_CELL_TYPE]));
|
|
113
125
|
|
|
114
126
|
}
|
|
115
127
|
|
|
128
|
+
protected setCellContext(cellHandle: number, key: string, value: unknown): void {
|
|
129
|
+
let cellContext = this.cellContexts.get(cellHandle);
|
|
130
|
+
if (!cellContext) {
|
|
131
|
+
cellContext = {};
|
|
132
|
+
this.cellContexts.set(cellHandle, cellContext);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
cellContext[key] = value;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
getCellContext(cellHandle: number): ContextMatcher {
|
|
139
|
+
return this.contextKeyService.createOverlay(Object.entries(this.cellContexts.get(cellHandle) ?? {}));
|
|
140
|
+
}
|
|
141
|
+
|
|
116
142
|
onDidEditorTextFocus(focus: boolean): void {
|
|
117
143
|
this.scopedStore.setContext('inputFocus', focus);
|
|
118
144
|
}
|
|
@@ -121,6 +121,10 @@ export class NotebookService implements Disposable {
|
|
|
121
121
|
// This ensures that all text models are available in the plugin host
|
|
122
122
|
this.textModelService.createTextModelsForNotebook(model);
|
|
123
123
|
this.didAddNotebookDocumentEmitter.fire(model);
|
|
124
|
+
model.onDidDispose(() => {
|
|
125
|
+
this.notebookModels.delete(resource.uri.toString());
|
|
126
|
+
this.didRemoveNotebookDocumentEmitter.fire(model);
|
|
127
|
+
});
|
|
124
128
|
return model;
|
|
125
129
|
}
|
|
126
130
|
|
|
@@ -109,8 +109,13 @@
|
|
|
109
109
|
flex-grow: 1;
|
|
110
110
|
}
|
|
111
111
|
|
|
112
|
-
.notebook-cell-
|
|
113
|
-
|
|
112
|
+
.notebook-cell-language-label {
|
|
113
|
+
padding: 0 5px;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
.notebook-cell-language-label:hover {
|
|
117
|
+
cursor: pointer;
|
|
118
|
+
background-color: var(--theia-toolbar-hoverBackground);
|
|
114
119
|
}
|
|
115
120
|
|
|
116
121
|
.notebook-cell-status-item {
|
|
@@ -213,8 +218,9 @@
|
|
|
213
218
|
cursor: pointer;
|
|
214
219
|
}
|
|
215
220
|
|
|
216
|
-
.theia-notebook-main-toolbar-item:hover {
|
|
217
|
-
background-color:
|
|
221
|
+
.theia-notebook-main-toolbar-item.theia-mod-disabled:hover {
|
|
222
|
+
background-color: transparent;
|
|
223
|
+
cursor: default;
|
|
218
224
|
}
|
|
219
225
|
|
|
220
226
|
.theia-notebook-main-toolbar-item-text {
|
|
@@ -265,3 +271,12 @@
|
|
|
265
271
|
background-color: var(--theia-notebook-focusedCellBorder);
|
|
266
272
|
width: 100%;
|
|
267
273
|
}
|
|
274
|
+
|
|
275
|
+
.theia-notebook-collapsed-output {
|
|
276
|
+
padding: 4px 8px;
|
|
277
|
+
color: var(--theia-foreground);
|
|
278
|
+
margin-left: 30px;
|
|
279
|
+
font-size: 14px;
|
|
280
|
+
line-height: 22px;
|
|
281
|
+
opacity: 0.7;
|
|
282
|
+
}
|
|
@@ -42,7 +42,8 @@ const DEFAULT_EDITOR_OPTIONS: MonacoEditor.IOptions = {
|
|
|
42
42
|
scrollbar: {
|
|
43
43
|
...MonacoEditorProvider.inlineOptions.scrollbar,
|
|
44
44
|
alwaysConsumeMouseWheel: false
|
|
45
|
-
}
|
|
45
|
+
},
|
|
46
|
+
lineDecorationsWidth: 10,
|
|
46
47
|
};
|
|
47
48
|
|
|
48
49
|
export class CellEditor extends React.Component<CellEditorProps, {}> {
|
|
@@ -56,6 +57,15 @@ export class CellEditor extends React.Component<CellEditorProps, {}> {
|
|
|
56
57
|
this.toDispose.push(this.props.cell.onWillFocusCellEditor(() => {
|
|
57
58
|
this.editor?.getControl().focus();
|
|
58
59
|
}));
|
|
60
|
+
|
|
61
|
+
this.toDispose.push(this.props.cell.onDidChangeEditorOptions(options => {
|
|
62
|
+
this.editor?.getControl().updateOptions(options);
|
|
63
|
+
}));
|
|
64
|
+
|
|
65
|
+
this.toDispose.push(this.props.cell.onDidChangeLanguage(language => {
|
|
66
|
+
this.editor?.setLanguage(language);
|
|
67
|
+
}));
|
|
68
|
+
|
|
59
69
|
this.toDispose.push(this.props.notebookModel.onDidChangeSelectedCell(() => {
|
|
60
70
|
if (this.props.notebookModel.selectedCell !== this.props.cell && this.editor?.getControl().hasTextFocus()) {
|
|
61
71
|
if (document.activeElement && 'blur' in document.activeElement) {
|
|
@@ -96,7 +106,7 @@ export class CellEditor extends React.Component<CellEditorProps, {}> {
|
|
|
96
106
|
editorModel,
|
|
97
107
|
editorNode,
|
|
98
108
|
monacoServices,
|
|
99
|
-
DEFAULT_EDITOR_OPTIONS,
|
|
109
|
+
{ ...DEFAULT_EDITOR_OPTIONS, ...cell.editorOptions },
|
|
100
110
|
[[IContextKeyService, this.props.notebookContextManager.scopedStore]]);
|
|
101
111
|
this.toDispose.push(this.editor);
|
|
102
112
|
this.editor.setLanguage(cell.language);
|
|
@@ -45,7 +45,7 @@ export class NotebookCellListView extends React.Component<CellListProps, Noteboo
|
|
|
45
45
|
|
|
46
46
|
constructor(props: CellListProps) {
|
|
47
47
|
super(props);
|
|
48
|
-
this.state = { selectedCell:
|
|
48
|
+
this.state = { selectedCell: props.notebookModel.selectedCell, dragOverIndicator: undefined };
|
|
49
49
|
this.toDispose.push(props.notebookModel.onDidAddOrRemoveCell(e => {
|
|
50
50
|
if (e.newCellIds && e.newCellIds.length > 0) {
|
|
51
51
|
this.setState({ ...this.state, selectedCell: this.props.notebookModel.cells.find(model => model.handle === e.newCellIds![e.newCellIds!.length - 1]) });
|
|
@@ -89,7 +89,10 @@ export class NotebookCellListView extends React.Component<CellListProps, Noteboo
|
|
|
89
89
|
{this.renderCellContent(cell, index)}
|
|
90
90
|
</div>
|
|
91
91
|
{this.state.selectedCell === cell &&
|
|
92
|
-
this.props.toolbarRenderer.renderCellToolbar(NotebookCellActionContribution.ACTION_MENU,
|
|
92
|
+
this.props.toolbarRenderer.renderCellToolbar(NotebookCellActionContribution.ACTION_MENU, cell, {
|
|
93
|
+
contextMenuArgs: () => [cell], commandArgs: () => [this.props.notebookModel]
|
|
94
|
+
})
|
|
95
|
+
}
|
|
93
96
|
</li>
|
|
94
97
|
{this.shouldRenderDragOverIndicator(cell, 'bottom') && <CellDropIndicator />}
|
|
95
98
|
</React.Fragment>
|
|
@@ -20,9 +20,7 @@ import { inject, injectable } from '@theia/core/shared/inversify';
|
|
|
20
20
|
import { ContextKeyService } from '@theia/core/lib/browser/context-key-service';
|
|
21
21
|
import { NotebookCellSidebar, NotebookCellToolbar } from './notebook-cell-toolbar';
|
|
22
22
|
import { ContextMenuRenderer } from '@theia/core/lib/browser';
|
|
23
|
-
import { NotebookModel } from '../view-model/notebook-model';
|
|
24
23
|
import { NotebookCellModel } from '../view-model/notebook-cell-model';
|
|
25
|
-
import { NotebookCellOutputModel } from '../view-model/notebook-cell-output-model';
|
|
26
24
|
import { NotebookContextManager } from '../service/notebook-context-manager';
|
|
27
25
|
|
|
28
26
|
export interface NotebookCellToolbarItem {
|
|
@@ -34,6 +32,11 @@ export interface NotebookCellToolbarItem {
|
|
|
34
32
|
contextKeys?: Set<string>
|
|
35
33
|
}
|
|
36
34
|
|
|
35
|
+
export interface toolbarItemOptions {
|
|
36
|
+
contextMenuArgs?: () => unknown[];
|
|
37
|
+
commandArgs?: () => unknown[];
|
|
38
|
+
}
|
|
39
|
+
|
|
37
40
|
@injectable()
|
|
38
41
|
export class NotebookCellToolbarFactory {
|
|
39
42
|
|
|
@@ -52,32 +55,31 @@ export class NotebookCellToolbarFactory {
|
|
|
52
55
|
@inject(NotebookContextManager)
|
|
53
56
|
protected readonly notebookContextManager: NotebookContextManager;
|
|
54
57
|
|
|
55
|
-
renderCellToolbar(menuPath: string[],
|
|
56
|
-
return <NotebookCellToolbar getMenuItems={() => this.getMenuItems(menuPath,
|
|
58
|
+
renderCellToolbar(menuPath: string[], cell: NotebookCellModel, itemOptions: toolbarItemOptions): React.ReactNode {
|
|
59
|
+
return <NotebookCellToolbar getMenuItems={() => this.getMenuItems(menuPath, cell, itemOptions)}
|
|
57
60
|
onContextKeysChanged={this.notebookContextManager.onDidChangeContext} />;
|
|
58
61
|
}
|
|
59
62
|
|
|
60
|
-
renderSidebar(menuPath: string[],
|
|
61
|
-
return <NotebookCellSidebar getMenuItems={() => this.getMenuItems(menuPath,
|
|
63
|
+
renderSidebar(menuPath: string[], cell: NotebookCellModel, itemOptions: toolbarItemOptions): React.ReactNode {
|
|
64
|
+
return <NotebookCellSidebar getMenuItems={() => this.getMenuItems(menuPath, cell, itemOptions)}
|
|
62
65
|
onContextKeysChanged={this.notebookContextManager.onDidChangeContext} />;
|
|
63
66
|
}
|
|
64
67
|
|
|
65
|
-
private getMenuItems(menuItemPath: string[],
|
|
68
|
+
private getMenuItems(menuItemPath: string[], cell: NotebookCellModel, itemOptions: toolbarItemOptions): NotebookCellToolbarItem[] {
|
|
66
69
|
const inlineItems: NotebookCellToolbarItem[] = [];
|
|
67
|
-
|
|
68
70
|
for (const menuNode of this.menuRegistry.getMenu(menuItemPath).children) {
|
|
69
|
-
if (!menuNode.when || this.
|
|
71
|
+
if (!menuNode.when || this.notebookContextManager.getCellContext(cell.handle).match(menuNode.when, this.notebookContextManager.context)) {
|
|
70
72
|
if (menuNode.role === CompoundMenuNodeRole.Flat) {
|
|
71
|
-
inlineItems.push(...menuNode.children?.map(child => this.createToolbarItem(child,
|
|
73
|
+
inlineItems.push(...menuNode.children?.map(child => this.createToolbarItem(child, itemOptions)) ?? []);
|
|
72
74
|
} else {
|
|
73
|
-
inlineItems.push(this.createToolbarItem(menuNode,
|
|
75
|
+
inlineItems.push(this.createToolbarItem(menuNode, itemOptions));
|
|
74
76
|
}
|
|
75
77
|
}
|
|
76
78
|
}
|
|
77
79
|
return inlineItems;
|
|
78
80
|
}
|
|
79
81
|
|
|
80
|
-
private createToolbarItem(menuNode: MenuNode,
|
|
82
|
+
private createToolbarItem(menuNode: MenuNode, itemOptions: toolbarItemOptions): NotebookCellToolbarItem {
|
|
81
83
|
const menuPath = menuNode.role === CompoundMenuNodeRole.Submenu ? this.menuRegistry.getPath(menuNode) : undefined;
|
|
82
84
|
return {
|
|
83
85
|
id: menuNode.id,
|
|
@@ -89,11 +91,11 @@ export class NotebookCellToolbarFactory {
|
|
|
89
91
|
anchor: e.nativeEvent,
|
|
90
92
|
menuPath,
|
|
91
93
|
includeAnchorArg: false,
|
|
92
|
-
args:
|
|
94
|
+
args: itemOptions.contextMenuArgs?.(),
|
|
93
95
|
context: this.notebookContextManager.context
|
|
94
96
|
}) :
|
|
95
|
-
() => this.commandRegistry.executeCommand(menuNode.command!,
|
|
96
|
-
isVisible: () => menuPath ? true : Boolean(this.commandRegistry.getVisibleHandler(menuNode.command!,
|
|
97
|
+
() => this.commandRegistry.executeCommand(menuNode.command!, ...(itemOptions.commandArgs?.() ?? [])),
|
|
98
|
+
isVisible: () => menuPath ? true : Boolean(this.commandRegistry.getVisibleHandler(menuNode.command!, ...(itemOptions.commandArgs?.() ?? []))),
|
|
97
99
|
contextKeys: menuNode.when ? this.contextKeyService.parseKeys(menuNode.when) : undefined
|
|
98
100
|
};
|
|
99
101
|
}
|
|
@@ -35,8 +35,9 @@ abstract class NotebookCellActionBar extends React.Component<NotebookCellToolbar
|
|
|
35
35
|
constructor(props: NotebookCellToolbarProps) {
|
|
36
36
|
super(props);
|
|
37
37
|
this.toDispose.push(props.onContextKeysChanged(e => {
|
|
38
|
-
|
|
39
|
-
|
|
38
|
+
const menuItems = this.props.getMenuItems();
|
|
39
|
+
if (menuItems.some(item => item.contextKeys ? e.affects(item.contextKeys) : false)) {
|
|
40
|
+
this.setState({ inlineItems: menuItems });
|
|
40
41
|
}
|
|
41
42
|
}));
|
|
42
43
|
this.state = { inlineItems: this.props.getMenuItems() };
|
|
@@ -24,11 +24,11 @@ import { NotebookModel } from '../view-model/notebook-model';
|
|
|
24
24
|
import { CellEditor } from './notebook-cell-editor';
|
|
25
25
|
import { CellRenderer } from './notebook-cell-list-view';
|
|
26
26
|
import { NotebookCellToolbarFactory } from './notebook-cell-toolbar-factory';
|
|
27
|
-
import { NotebookCellActionContribution } from '../contributions/notebook-cell-actions-contribution';
|
|
27
|
+
import { NotebookCellActionContribution, NotebookCellCommands } from '../contributions/notebook-cell-actions-contribution';
|
|
28
28
|
import { CellExecution, NotebookExecutionStateService } from '../service/notebook-execution-state-service';
|
|
29
29
|
import { codicon } from '@theia/core/lib/browser';
|
|
30
30
|
import { NotebookCellExecutionState } from '../../common';
|
|
31
|
-
import { DisposableCollection } from '@theia/core';
|
|
31
|
+
import { CommandRegistry, DisposableCollection, nls } from '@theia/core';
|
|
32
32
|
import { NotebookContextManager } from '../service/notebook-context-manager';
|
|
33
33
|
import { NotebookViewportService } from './notebook-viewport-service';
|
|
34
34
|
import { EditorPreferences } from '@theia/editor/lib/browser';
|
|
@@ -61,13 +61,19 @@ export class NotebookCodeCellRenderer implements CellRenderer {
|
|
|
61
61
|
@inject(EditorPreferences)
|
|
62
62
|
protected readonly editorPreferences: EditorPreferences;
|
|
63
63
|
|
|
64
|
+
@inject(CommandRegistry)
|
|
65
|
+
protected readonly commandRegistry: CommandRegistry;
|
|
66
|
+
|
|
64
67
|
protected fontInfo: BareFontInfo | undefined;
|
|
65
68
|
|
|
66
69
|
render(notebookModel: NotebookModel, cell: NotebookCellModel, handle: number): React.ReactNode {
|
|
67
70
|
return <div>
|
|
68
71
|
<div className='theia-notebook-cell-with-sidebar'>
|
|
69
72
|
<div className='theia-notebook-cell-sidebar'>
|
|
70
|
-
{this.notebookCellToolbarFactory.renderSidebar(NotebookCellActionContribution.CODE_CELL_SIDEBAR_MENU,
|
|
73
|
+
{this.notebookCellToolbarFactory.renderSidebar(NotebookCellActionContribution.CODE_CELL_SIDEBAR_MENU, cell, {
|
|
74
|
+
contextMenuArgs: () => [cell], commandArgs: () => [notebookModel, cell]
|
|
75
|
+
})
|
|
76
|
+
}
|
|
71
77
|
<CodeCellExecutionOrder cell={cell} />
|
|
72
78
|
</div>
|
|
73
79
|
<div className='theia-notebook-cell-editor-container'>
|
|
@@ -76,13 +82,19 @@ export class NotebookCodeCellRenderer implements CellRenderer {
|
|
|
76
82
|
notebookContextManager={this.notebookContextManager}
|
|
77
83
|
notebookViewportService={this.notebookViewportService}
|
|
78
84
|
fontInfo={this.getOrCreateMonacoFontInfo()} />
|
|
79
|
-
<NotebookCodeCellStatus cell={cell}
|
|
85
|
+
<NotebookCodeCellStatus cell={cell} notebook={notebookModel}
|
|
86
|
+
commandRegistry={this.commandRegistry}
|
|
87
|
+
executionStateService={this.executionStateService}
|
|
88
|
+
onClick={() => cell.requestFocusEditor()} />
|
|
80
89
|
</div >
|
|
81
90
|
</div >
|
|
82
91
|
<div className='theia-notebook-cell-with-sidebar'>
|
|
83
92
|
<NotebookCodeCellOutputs cell={cell} notebook={notebookModel} outputWebviewFactory={this.cellOutputWebviewFactory}
|
|
84
93
|
renderSidebar={() =>
|
|
85
|
-
this.notebookCellToolbarFactory.renderSidebar(NotebookCellActionContribution.OUTPUT_SIDEBAR_MENU,
|
|
94
|
+
this.notebookCellToolbarFactory.renderSidebar(NotebookCellActionContribution.OUTPUT_SIDEBAR_MENU, cell, {
|
|
95
|
+
contextMenuArgs: () => [notebookModel, cell, cell.outputs[0]]
|
|
96
|
+
})
|
|
97
|
+
} />
|
|
86
98
|
</div>
|
|
87
99
|
</div >;
|
|
88
100
|
}
|
|
@@ -108,7 +120,9 @@ export class NotebookCodeCellRenderer implements CellRenderer {
|
|
|
108
120
|
}
|
|
109
121
|
|
|
110
122
|
export interface NotebookCodeCellStatusProps {
|
|
123
|
+
notebook: NotebookModel;
|
|
111
124
|
cell: NotebookCellModel;
|
|
125
|
+
commandRegistry: CommandRegistry;
|
|
112
126
|
executionStateService: NotebookExecutionStateService;
|
|
113
127
|
onClick: () => void;
|
|
114
128
|
}
|
|
@@ -146,6 +160,10 @@ export class NotebookCodeCellStatus extends React.Component<NotebookCodeCellStat
|
|
|
146
160
|
}
|
|
147
161
|
}
|
|
148
162
|
}));
|
|
163
|
+
|
|
164
|
+
this.toDispose.push(props.cell.onDidChangeLanguage(() => {
|
|
165
|
+
this.forceUpdate();
|
|
166
|
+
}));
|
|
149
167
|
}
|
|
150
168
|
|
|
151
169
|
override componentWillUnmount(): void {
|
|
@@ -158,7 +176,9 @@ export class NotebookCodeCellStatus extends React.Component<NotebookCodeCellStat
|
|
|
158
176
|
{this.renderExecutionState()}
|
|
159
177
|
</div>
|
|
160
178
|
<div className='notebook-cell-status-right'>
|
|
161
|
-
<span
|
|
179
|
+
<span className='notebook-cell-language-label' onClick={() => {
|
|
180
|
+
this.props.commandRegistry.executeCommand(NotebookCellCommands.CHANGE_CELL_LANGUAGE.id, this.props.notebook, this.props.cell);
|
|
181
|
+
}}>{this.props.cell.languageName}</span>
|
|
162
182
|
</div>
|
|
163
183
|
</div>;
|
|
164
184
|
}
|
|
@@ -223,19 +243,15 @@ export class NotebookCodeCellOutputs extends React.Component<NotebookCellOutputP
|
|
|
223
243
|
|
|
224
244
|
override async componentDidMount(): Promise<void> {
|
|
225
245
|
const { cell, notebook, outputWebviewFactory } = this.props;
|
|
226
|
-
this.toDispose.push(cell.onDidChangeOutputs(
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
this.forceUpdate();
|
|
231
|
-
return webview;
|
|
232
|
-
});
|
|
233
|
-
this.forceUpdate();
|
|
234
|
-
} else if (this.outputsWebviewPromise && cell.outputs.length === 0 && cell.internalMetadata.runEndTime) {
|
|
235
|
-
(await this.outputsWebviewPromise).dispose();
|
|
246
|
+
this.toDispose.push(cell.onDidChangeOutputs(() => this.updateOutputs()));
|
|
247
|
+
this.toDispose.push(cell.onDidChangeOutputVisibility(visible => {
|
|
248
|
+
if (!visible && this.outputsWebview) {
|
|
249
|
+
this.outputsWebview?.dispose();
|
|
236
250
|
this.outputsWebview = undefined;
|
|
237
251
|
this.outputsWebviewPromise = undefined;
|
|
238
252
|
this.forceUpdate();
|
|
253
|
+
} else {
|
|
254
|
+
this.updateOutputs();
|
|
239
255
|
}
|
|
240
256
|
}));
|
|
241
257
|
if (cell.outputs.length > 0) {
|
|
@@ -247,6 +263,23 @@ export class NotebookCodeCellOutputs extends React.Component<NotebookCellOutputP
|
|
|
247
263
|
}
|
|
248
264
|
}
|
|
249
265
|
|
|
266
|
+
protected async updateOutputs(): Promise<void> {
|
|
267
|
+
const { cell, notebook, outputWebviewFactory } = this.props;
|
|
268
|
+
if (!this.outputsWebviewPromise && cell.outputs.length > 0) {
|
|
269
|
+
this.outputsWebviewPromise = outputWebviewFactory(cell, notebook).then(webview => {
|
|
270
|
+
this.outputsWebview = webview;
|
|
271
|
+
this.forceUpdate();
|
|
272
|
+
return webview;
|
|
273
|
+
});
|
|
274
|
+
this.forceUpdate();
|
|
275
|
+
} else if (this.outputsWebviewPromise && cell.outputs.length === 0 && cell.internalMetadata.runEndTime) {
|
|
276
|
+
(await this.outputsWebviewPromise).dispose();
|
|
277
|
+
this.outputsWebview = undefined;
|
|
278
|
+
this.outputsWebviewPromise = undefined;
|
|
279
|
+
this.forceUpdate();
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
250
283
|
override async componentDidUpdate(): Promise<void> {
|
|
251
284
|
if (!(await this.outputsWebviewPromise)?.isAttached()) {
|
|
252
285
|
(await this.outputsWebviewPromise)?.attachWebview();
|
|
@@ -259,12 +292,12 @@ export class NotebookCodeCellOutputs extends React.Component<NotebookCellOutputP
|
|
|
259
292
|
}
|
|
260
293
|
|
|
261
294
|
override render(): React.ReactNode {
|
|
262
|
-
return this.outputsWebview ?
|
|
295
|
+
return this.outputsWebview && this.props.cell.outputVisible ?
|
|
263
296
|
<>
|
|
264
297
|
{this.props.renderSidebar()}
|
|
265
298
|
{this.outputsWebview.render()}
|
|
266
299
|
</> :
|
|
267
|
-
<></>;
|
|
300
|
+
this.props.cell.outputs?.length ? <i className='theia-notebook-collapsed-output'>{nls.localizeByDefault('Outputs are collapsed')}</i> : <></>;
|
|
268
301
|
|
|
269
302
|
}
|
|
270
303
|
|
|
@@ -57,6 +57,10 @@ export class NotebookMainToolbar extends React.Component<NotebookMainToolbarProp
|
|
|
57
57
|
|
|
58
58
|
protected toDispose = new DisposableCollection();
|
|
59
59
|
|
|
60
|
+
protected nativeSubmenus = [
|
|
61
|
+
NotebookMenus.NOTEBOOK_MAIN_TOOLBAR_CELL_ADD_GROUP[NotebookMenus.NOTEBOOK_MAIN_TOOLBAR_CELL_ADD_GROUP.length - 1],
|
|
62
|
+
NotebookMenus.NOTEBOOK_MAIN_TOOLBAR_EXECUTION_GROUP[NotebookMenus.NOTEBOOK_MAIN_TOOLBAR_EXECUTION_GROUP.length - 1]];
|
|
63
|
+
|
|
60
64
|
constructor(props: NotebookMainToolbarProps) {
|
|
61
65
|
super(props);
|
|
62
66
|
|
|
@@ -107,41 +111,46 @@ export class NotebookMainToolbar extends React.Component<NotebookMainToolbarProp
|
|
|
107
111
|
</div>;
|
|
108
112
|
}
|
|
109
113
|
|
|
110
|
-
protected renderMenuItem(item: MenuNode): React.ReactNode {
|
|
114
|
+
protected renderMenuItem(item: MenuNode, submenu?: string): React.ReactNode {
|
|
111
115
|
if (item.role === CompoundMenuNodeRole.Group) {
|
|
112
|
-
const itemNodes = ArrayUtils.coalesce(item.children?.map(child => this.renderMenuItem(child)) ?? []);
|
|
116
|
+
const itemNodes = ArrayUtils.coalesce(item.children?.map(child => this.renderMenuItem(child, item.id)) ?? []);
|
|
113
117
|
return <React.Fragment key={item.id}>
|
|
114
118
|
{itemNodes}
|
|
115
119
|
{itemNodes && itemNodes.length > 0 && <span key={`${item.id}-separator`} className='theia-notebook-toolbar-separator'></span>}
|
|
116
120
|
</React.Fragment>;
|
|
117
|
-
} else if (!item.when || this.props.contextKeyService.match(item.when, this.props.editorNode)) {
|
|
121
|
+
} else if ((this.nativeSubmenus.includes(submenu ?? '')) || !item.when || this.props.contextKeyService.match(item.when, this.props.editorNode)) {
|
|
118
122
|
const visibleCommand = Boolean(this.props.commandRegistry.getVisibleHandler(item.command ?? '', this.props.notebookModel));
|
|
119
123
|
if (!visibleCommand) {
|
|
120
124
|
return undefined;
|
|
121
125
|
}
|
|
122
|
-
const
|
|
123
|
-
|
|
126
|
+
const command = this.props.commandRegistry.getCommand(item.command ?? '') as NotebookCommand | undefined;
|
|
127
|
+
const label = command?.shortTitle ?? item.label;
|
|
128
|
+
const title = command?.tooltip ?? item.label;
|
|
129
|
+
return <div key={item.id} title={title} className={`theia-notebook-main-toolbar-item action-label${this.getAdditionalClasses(item)}`}
|
|
124
130
|
onClick={() => {
|
|
125
|
-
if (item.command) {
|
|
126
|
-
this.props.commandRegistry.executeCommand(item.command, this.props.notebookModel);
|
|
131
|
+
if (item.command && (!item.when || this.props.contextKeyService.match(item.when, this.props.editorNode))) {
|
|
132
|
+
this.props.commandRegistry.executeCommand(item.command, this.props.notebookModel.uri);
|
|
127
133
|
}
|
|
128
134
|
}}>
|
|
129
135
|
<span className={item.icon} />
|
|
130
|
-
<span className='theia-notebook-main-toolbar-item-text'>{
|
|
136
|
+
<span className='theia-notebook-main-toolbar-item-text'>{label}</span>
|
|
131
137
|
</div>;
|
|
132
138
|
}
|
|
133
139
|
return undefined;
|
|
134
140
|
}
|
|
135
141
|
|
|
136
|
-
|
|
142
|
+
protected getMenuItems(): readonly MenuNode[] {
|
|
137
143
|
const menuPath = NotebookMenus.NOTEBOOK_MAIN_TOOLBAR;
|
|
138
144
|
const pluginCommands = this.props.menuRegistry.getMenuNode(menuPath).children;
|
|
139
145
|
const theiaCommands = this.props.menuRegistry.getMenu([menuPath]).children;
|
|
140
|
-
// TODO add specifc arguments to commands
|
|
141
146
|
return theiaCommands.concat(pluginCommands);
|
|
142
147
|
}
|
|
143
148
|
|
|
144
|
-
|
|
149
|
+
protected getAdditionalClasses(item: MenuNode): string {
|
|
150
|
+
return !item.when || this.props.contextKeyService.match(item.when, this.props.editorNode) ? '' : ' theia-mod-disabled';
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
protected getAllContextKeys(menus: readonly MenuNode[], keySet: Set<string>): void {
|
|
145
154
|
menus.filter(item => item.when)
|
|
146
155
|
.forEach(item => this.props.contextKeyService.parseKeys(item.when!)?.forEach(key => keySet.add(key)));
|
|
147
156
|
|