@jupyterlab/cell-toolbar 4.0.0-alpha.7 → 4.0.0-beta.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/celltoolbartracker.d.ts +5 -0
- package/lib/celltoolbartracker.js +134 -25
- package/lib/celltoolbartracker.js.map +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.js +1 -1
- package/lib/index.js.map +1 -1
- package/package.json +19 -19
- package/src/celltoolbartracker.ts +479 -0
- package/src/index.ts +9 -0
- package/style/base.css +9 -8
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
import { ToolbarRegistry } from '@jupyterlab/apputils';
|
|
2
|
+
import { CellModel } from '@jupyterlab/cells';
|
|
2
3
|
import { DocumentRegistry } from '@jupyterlab/docregistry';
|
|
3
4
|
import { Notebook, NotebookPanel } from '@jupyterlab/notebook';
|
|
4
5
|
import { IObservableList } from '@jupyterlab/observables';
|
|
5
6
|
import { CommandRegistry } from '@lumino/commands';
|
|
6
7
|
import { IDisposable } from '@lumino/disposable';
|
|
7
8
|
import { Widget } from '@lumino/widgets';
|
|
9
|
+
import { IMapChange } from '@jupyter/ydoc';
|
|
8
10
|
/**
|
|
9
11
|
* Watch a notebook so that a cell toolbar appears on the active cell
|
|
10
12
|
*/
|
|
11
13
|
export declare class CellToolbarTracker implements IDisposable {
|
|
12
14
|
constructor(panel: NotebookPanel, toolbar: IObservableList<ToolbarRegistry.IToolbarItem>);
|
|
15
|
+
_onMetadataChanged(model: CellModel, args: IMapChange): void;
|
|
13
16
|
_onActiveCellChanged(notebook: Notebook): void;
|
|
14
17
|
get isDisposed(): boolean;
|
|
15
18
|
dispose(): void;
|
|
@@ -32,9 +35,11 @@ export declare class CellToolbarTracker implements IDisposable {
|
|
|
32
35
|
* @returns `true` if the first line of the output overlaps with the cell toolbar, `false` otherwise
|
|
33
36
|
*/
|
|
34
37
|
private _markdownOverlapsToolbar;
|
|
38
|
+
private _outputOverlapsToolbar;
|
|
35
39
|
private _codeOverlapsToolbar;
|
|
36
40
|
private _cellEditorWidgetLeft;
|
|
37
41
|
private _cellEditorWidgetRight;
|
|
42
|
+
private _cellToolbarRect;
|
|
38
43
|
private _cellToolbarLeft;
|
|
39
44
|
private _isDisposed;
|
|
40
45
|
private _panel;
|
|
@@ -4,9 +4,17 @@
|
|
|
4
4
|
|----------------------------------------------------------------------------*/
|
|
5
5
|
import { createDefaultFactory } from '@jupyterlab/apputils';
|
|
6
6
|
import { ObservableList } from '@jupyterlab/observables';
|
|
7
|
-
import { Toolbar } from '@jupyterlab/ui-components';
|
|
8
|
-
import {
|
|
7
|
+
import { ReactWidget, Toolbar } from '@jupyterlab/ui-components';
|
|
8
|
+
import { some } from '@lumino/algorithm';
|
|
9
9
|
import { Signal } from '@lumino/signaling';
|
|
10
|
+
/*
|
|
11
|
+
* Text mime types
|
|
12
|
+
*/
|
|
13
|
+
const TEXT_MIME_TYPES = [
|
|
14
|
+
'text/plain',
|
|
15
|
+
'application/vnd.jupyter.stdout',
|
|
16
|
+
'application/vnd.jupyter.stderr'
|
|
17
|
+
];
|
|
10
18
|
/**
|
|
11
19
|
* Widget cell toolbar classes
|
|
12
20
|
*/
|
|
@@ -21,6 +29,7 @@ const TOOLBAR_OVERLAP_CLASS = 'jp-toolbar-overlap';
|
|
|
21
29
|
*/
|
|
22
30
|
export class CellToolbarTracker {
|
|
23
31
|
constructor(panel, toolbar) {
|
|
32
|
+
var _a;
|
|
24
33
|
this._isDisposed = false;
|
|
25
34
|
this._panel = panel;
|
|
26
35
|
this._previousActiveCell = this._panel.content.activeCell;
|
|
@@ -28,21 +37,52 @@ export class CellToolbarTracker {
|
|
|
28
37
|
this._onToolbarChanged();
|
|
29
38
|
this._toolbar.changed.connect(this._onToolbarChanged, this);
|
|
30
39
|
// Only add the toolbar to the notebook's active cell (if any) once it has fully rendered and been revealed.
|
|
31
|
-
panel.revealed.then(() =>
|
|
40
|
+
void panel.revealed.then(() => {
|
|
41
|
+
// Wait one frame (at 60 fps) for the panel to render the first cell, then display the cell toolbar on it if possible.
|
|
42
|
+
setTimeout(() => {
|
|
43
|
+
this._onActiveCellChanged(panel.content);
|
|
44
|
+
}, 1000 / 60);
|
|
45
|
+
});
|
|
46
|
+
// Check whether the toolbar should be rendered upon a layout change
|
|
47
|
+
panel.content.renderingLayoutChanged.connect(this._onActiveCellChanged, this);
|
|
32
48
|
// Handle subsequent changes of active cell.
|
|
33
49
|
panel.content.activeCellChanged.connect(this._onActiveCellChanged, this);
|
|
50
|
+
(_a = panel.content.activeCell) === null || _a === void 0 ? void 0 : _a.model.metadataChanged.connect(this._onMetadataChanged, this);
|
|
51
|
+
panel.disposed.connect(() => {
|
|
52
|
+
var _a;
|
|
53
|
+
panel.content.activeCellChanged.disconnect(this._onActiveCellChanged);
|
|
54
|
+
(_a = panel.content.activeCell) === null || _a === void 0 ? void 0 : _a.model.metadataChanged.disconnect(this._onMetadataChanged);
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
_onMetadataChanged(model, args) {
|
|
58
|
+
if (args.key === 'jupyter') {
|
|
59
|
+
if (typeof args.newValue === 'object' &&
|
|
60
|
+
args.newValue.source_hidden === true &&
|
|
61
|
+
(args.type === 'add' || args.type === 'change')) {
|
|
62
|
+
// Cell just became hidden; remove toolbar
|
|
63
|
+
this._removeToolbar(model);
|
|
64
|
+
}
|
|
65
|
+
// Check whether input visibility changed
|
|
66
|
+
else if (typeof args.oldValue === 'object' &&
|
|
67
|
+
args.oldValue.source_hidden === true) {
|
|
68
|
+
// Cell just became visible; add toolbar
|
|
69
|
+
this._addToolbar(model);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
34
72
|
}
|
|
35
73
|
_onActiveCellChanged(notebook) {
|
|
36
|
-
if (this._previousActiveCell) {
|
|
74
|
+
if (this._previousActiveCell && !this._previousActiveCell.isDisposed) {
|
|
75
|
+
// Disposed cells do not have a model anymore.
|
|
37
76
|
this._removeToolbar(this._previousActiveCell.model);
|
|
77
|
+
this._previousActiveCell.model.metadataChanged.disconnect(this._onMetadataChanged);
|
|
38
78
|
}
|
|
39
79
|
const activeCell = notebook.activeCell;
|
|
40
|
-
if (
|
|
80
|
+
if (activeCell === null || activeCell.inputHidden) {
|
|
41
81
|
return;
|
|
42
82
|
}
|
|
83
|
+
activeCell.model.metadataChanged.connect(this._onMetadataChanged, this);
|
|
43
84
|
this._addToolbar(activeCell.model);
|
|
44
85
|
this._previousActiveCell = activeCell;
|
|
45
|
-
this._updateCellForToolbarOverlap(activeCell);
|
|
46
86
|
}
|
|
47
87
|
get isDisposed() {
|
|
48
88
|
return this._isDisposed;
|
|
@@ -56,7 +96,9 @@ export class CellToolbarTracker {
|
|
|
56
96
|
this._toolbar.changed.disconnect(this._onToolbarChanged, this);
|
|
57
97
|
const cells = (_a = this._panel) === null || _a === void 0 ? void 0 : _a.context.model.cells;
|
|
58
98
|
if (cells) {
|
|
59
|
-
|
|
99
|
+
for (const model of cells) {
|
|
100
|
+
this._removeToolbar(model);
|
|
101
|
+
}
|
|
60
102
|
}
|
|
61
103
|
this._panel = null;
|
|
62
104
|
Signal.clearData(this);
|
|
@@ -66,15 +108,30 @@ export class CellToolbarTracker {
|
|
|
66
108
|
if (cell) {
|
|
67
109
|
const toolbarWidget = new Toolbar();
|
|
68
110
|
toolbarWidget.addClass(CELL_MENU_CLASS);
|
|
69
|
-
|
|
111
|
+
const promises = [];
|
|
112
|
+
for (const { name, widget } of this._toolbar) {
|
|
70
113
|
toolbarWidget.addItem(name, widget);
|
|
114
|
+
if (widget instanceof ReactWidget &&
|
|
115
|
+
widget.renderPromise !== undefined) {
|
|
116
|
+
widget.update();
|
|
117
|
+
promises.push(widget.renderPromise);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
// Wait for all the buttons to be rendered before attaching the toolbar.
|
|
121
|
+
Promise.all(promises)
|
|
122
|
+
.then(() => {
|
|
123
|
+
toolbarWidget.addClass(CELL_TOOLBAR_CLASS);
|
|
124
|
+
cell.layout.insertWidget(0, toolbarWidget);
|
|
125
|
+
// For rendered markdown, watch for resize events.
|
|
126
|
+
cell.displayChanged.connect(this._resizeEventCallback, this);
|
|
127
|
+
// Watch for changes in the cell's contents.
|
|
128
|
+
cell.model.contentChanged.connect(this._changedEventCallback, this);
|
|
129
|
+
// Hide the cell toolbar if it overlaps with cell contents
|
|
130
|
+
this._updateCellForToolbarOverlap(cell);
|
|
131
|
+
})
|
|
132
|
+
.catch(e => {
|
|
133
|
+
console.error('Error rendering buttons of the cell toolbar: ', e);
|
|
71
134
|
});
|
|
72
|
-
toolbarWidget.addClass(CELL_TOOLBAR_CLASS);
|
|
73
|
-
cell.layout.insertWidget(0, toolbarWidget);
|
|
74
|
-
// For rendered markdown, watch for resize events.
|
|
75
|
-
cell.displayChanged.connect(this._resizeEventCallback, this);
|
|
76
|
-
// Watch for changes in the cell's contents.
|
|
77
|
-
cell.model.contentChanged.connect(this._changedEventCallback, this);
|
|
78
135
|
}
|
|
79
136
|
}
|
|
80
137
|
_getCell(model) {
|
|
@@ -89,11 +146,13 @@ export class CellToolbarTracker {
|
|
|
89
146
|
_removeToolbar(model) {
|
|
90
147
|
const cell = this._getCell(model);
|
|
91
148
|
if (cell) {
|
|
92
|
-
this._findToolbarWidgets(cell).forEach(widget =>
|
|
149
|
+
this._findToolbarWidgets(cell).forEach(widget => {
|
|
150
|
+
widget.dispose();
|
|
151
|
+
});
|
|
93
152
|
// Attempt to remove the resize and changed event handlers.
|
|
94
153
|
cell.displayChanged.disconnect(this._resizeEventCallback, this);
|
|
95
|
-
cell.model.contentChanged.disconnect(this._changedEventCallback, this);
|
|
96
154
|
}
|
|
155
|
+
model.contentChanged.disconnect(this._changedEventCallback, this);
|
|
97
156
|
}
|
|
98
157
|
/**
|
|
99
158
|
* Call back on settings changes
|
|
@@ -134,6 +193,7 @@ export class CellToolbarTracker {
|
|
|
134
193
|
}
|
|
135
194
|
}
|
|
136
195
|
_cellToolbarOverlapsContents(activeCell) {
|
|
196
|
+
var _a;
|
|
137
197
|
const cellType = activeCell.model.type;
|
|
138
198
|
// If the toolbar is too large for the current cell, hide it.
|
|
139
199
|
const cellLeft = this._cellEditorWidgetLeft(activeCell);
|
|
@@ -151,7 +211,12 @@ export class CellToolbarTracker {
|
|
|
151
211
|
return this._markdownOverlapsToolbar(activeCell);
|
|
152
212
|
}
|
|
153
213
|
// Check for overlap in code content
|
|
154
|
-
|
|
214
|
+
if (((_a = this._panel) === null || _a === void 0 ? void 0 : _a.content.renderingLayout) === 'default') {
|
|
215
|
+
return this._codeOverlapsToolbar(activeCell);
|
|
216
|
+
}
|
|
217
|
+
else {
|
|
218
|
+
return this._outputOverlapsToolbar(activeCell);
|
|
219
|
+
}
|
|
155
220
|
}
|
|
156
221
|
/**
|
|
157
222
|
* Check for overlap between rendered Markdown and the cell toolbar
|
|
@@ -161,6 +226,9 @@ export class CellToolbarTracker {
|
|
|
161
226
|
*/
|
|
162
227
|
_markdownOverlapsToolbar(activeCell) {
|
|
163
228
|
const markdownOutput = activeCell.inputArea; // Rendered markdown appears in the input area
|
|
229
|
+
if (!markdownOutput) {
|
|
230
|
+
return false;
|
|
231
|
+
}
|
|
164
232
|
// Get the rendered markdown as a widget.
|
|
165
233
|
const markdownOutputWidget = markdownOutput.renderedInput;
|
|
166
234
|
const markdownOutputElement = markdownOutputWidget.node;
|
|
@@ -177,34 +245,74 @@ export class CellToolbarTracker {
|
|
|
177
245
|
const toolbarLeft = this._cellToolbarLeft(activeCell);
|
|
178
246
|
return toolbarLeft === null ? false : lineRight > toolbarLeft;
|
|
179
247
|
}
|
|
248
|
+
_outputOverlapsToolbar(activeCell) {
|
|
249
|
+
const outputArea = activeCell.outputArea.node;
|
|
250
|
+
if (outputArea) {
|
|
251
|
+
const outputs = outputArea.querySelectorAll('[data-mime-type]');
|
|
252
|
+
const toolbarRect = this._cellToolbarRect(activeCell);
|
|
253
|
+
if (toolbarRect) {
|
|
254
|
+
const { left: toolbarLeft, bottom: toolbarBottom } = toolbarRect;
|
|
255
|
+
return some(outputs, output => {
|
|
256
|
+
const node = output.firstElementChild;
|
|
257
|
+
if (node) {
|
|
258
|
+
const range = new Range();
|
|
259
|
+
if (TEXT_MIME_TYPES.includes(output.getAttribute('data-mime-type') || '')) {
|
|
260
|
+
// If the node is plain text, it's in a <pre>. To get the true bounding box of the
|
|
261
|
+
// text, the node contents need to be selected.
|
|
262
|
+
range.selectNodeContents(node);
|
|
263
|
+
}
|
|
264
|
+
else {
|
|
265
|
+
range.selectNode(node);
|
|
266
|
+
}
|
|
267
|
+
const { right: nodeRight, top: nodeTop } = range.getBoundingClientRect();
|
|
268
|
+
// Note: y-coordinate increases toward the bottom of page
|
|
269
|
+
return nodeRight > toolbarLeft && nodeTop < toolbarBottom;
|
|
270
|
+
}
|
|
271
|
+
return false;
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
return false;
|
|
276
|
+
}
|
|
180
277
|
_codeOverlapsToolbar(activeCell) {
|
|
181
278
|
const editorWidget = activeCell.editorWidget;
|
|
182
279
|
const editor = activeCell.editor;
|
|
280
|
+
if (!editorWidget || !editor) {
|
|
281
|
+
return false;
|
|
282
|
+
}
|
|
183
283
|
if (editor.lineCount < 1) {
|
|
184
284
|
return false; // Nothing in the editor
|
|
185
285
|
}
|
|
186
|
-
const codeMirrorLines = editorWidget.node.getElementsByClassName('
|
|
286
|
+
const codeMirrorLines = editorWidget.node.getElementsByClassName('cm-line');
|
|
187
287
|
if (codeMirrorLines.length < 1) {
|
|
188
288
|
return false; // No lines present
|
|
189
289
|
}
|
|
190
|
-
|
|
191
|
-
|
|
290
|
+
let lineRight = codeMirrorLines[0].getBoundingClientRect().left;
|
|
291
|
+
const range = document.createRange();
|
|
292
|
+
range.selectNodeContents(codeMirrorLines[0]);
|
|
293
|
+
lineRight += range.getBoundingClientRect().width;
|
|
192
294
|
const toolbarLeft = this._cellToolbarLeft(activeCell);
|
|
193
295
|
return toolbarLeft === null ? false : lineRight > toolbarLeft;
|
|
194
296
|
}
|
|
195
297
|
_cellEditorWidgetLeft(activeCell) {
|
|
196
|
-
|
|
298
|
+
var _a, _b;
|
|
299
|
+
return (_b = (_a = activeCell.editorWidget) === null || _a === void 0 ? void 0 : _a.node.getBoundingClientRect().left) !== null && _b !== void 0 ? _b : 0;
|
|
197
300
|
}
|
|
198
301
|
_cellEditorWidgetRight(activeCell) {
|
|
199
|
-
|
|
302
|
+
var _a, _b;
|
|
303
|
+
return (_b = (_a = activeCell.editorWidget) === null || _a === void 0 ? void 0 : _a.node.getBoundingClientRect().right) !== null && _b !== void 0 ? _b : 0;
|
|
200
304
|
}
|
|
201
|
-
|
|
305
|
+
_cellToolbarRect(activeCell) {
|
|
202
306
|
const toolbarWidgets = this._findToolbarWidgets(activeCell);
|
|
203
307
|
if (toolbarWidgets.length < 1) {
|
|
204
308
|
return null;
|
|
205
309
|
}
|
|
206
310
|
const activeCellToolbar = toolbarWidgets[0].node;
|
|
207
|
-
return activeCellToolbar.getBoundingClientRect()
|
|
311
|
+
return activeCellToolbar.getBoundingClientRect();
|
|
312
|
+
}
|
|
313
|
+
_cellToolbarLeft(activeCell) {
|
|
314
|
+
var _a;
|
|
315
|
+
return ((_a = this._cellToolbarRect(activeCell)) === null || _a === void 0 ? void 0 : _a.left) || null;
|
|
208
316
|
}
|
|
209
317
|
}
|
|
210
318
|
const defaultToolbarItems = [
|
|
@@ -237,7 +345,7 @@ const defaultToolbarItems = [
|
|
|
237
345
|
* Widget extension that creates a CellToolbarTracker each time a notebook is
|
|
238
346
|
* created.
|
|
239
347
|
*/
|
|
240
|
-
|
|
348
|
+
class CellBarExtension {
|
|
241
349
|
constructor(commands, toolbarFactory) {
|
|
242
350
|
this._commands = commands;
|
|
243
351
|
this._toolbarFactory = toolbarFactory !== null && toolbarFactory !== void 0 ? toolbarFactory : this.defaultToolbarFactory;
|
|
@@ -258,4 +366,5 @@ export class CellBarExtension {
|
|
|
258
366
|
}
|
|
259
367
|
}
|
|
260
368
|
CellBarExtension.FACTORY_NAME = 'Cell';
|
|
369
|
+
export { CellBarExtension };
|
|
261
370
|
//# sourceMappingURL=celltoolbartracker.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"celltoolbartracker.js","sourceRoot":"","sources":["../src/celltoolbartracker.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"celltoolbartracker.js","sourceRoot":"","sources":["../src/celltoolbartracker.ts"],"names":[],"mappings":"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"}
|
package/lib/index.d.ts
CHANGED
package/lib/index.js
CHANGED
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;+EAG+E;AAC/E;;;GAGG;AACH,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;+EAG+E;AAC/E;;;GAGG;AACH,cAAc,sBAAsB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jupyterlab/cell-toolbar",
|
|
3
|
-
"version": "4.0.0-
|
|
3
|
+
"version": "4.0.0-beta.0",
|
|
4
4
|
"description": "Contextual cell toolbar adapted from jlab-enhanced-cell-toolbar",
|
|
5
5
|
"homepage": "https://github.com/jupyterlab/jupyterlab",
|
|
6
6
|
"bugs": {
|
|
@@ -26,11 +26,11 @@
|
|
|
26
26
|
"lib/**/*.{d.ts,eot,gif,html,jpg,js,js.map,json,png,svg,woff2,ttf}",
|
|
27
27
|
"schema/*.json",
|
|
28
28
|
"style/**/*.{css,eot,gif,html,jpg,json,png,svg,woff2,ttf}",
|
|
29
|
-
"style/index.js"
|
|
29
|
+
"style/index.js",
|
|
30
|
+
"src/**/*.{ts,tsx}"
|
|
30
31
|
],
|
|
31
32
|
"scripts": {
|
|
32
33
|
"build": "tsc -b",
|
|
33
|
-
"build:all": "npm run build",
|
|
34
34
|
"build:test": "tsc --build tsconfig.test.json",
|
|
35
35
|
"clean": "rimraf lib && rimraf tsconfig.tsbuildinfo",
|
|
36
36
|
"test": "jest",
|
|
@@ -40,25 +40,25 @@
|
|
|
40
40
|
"watch": "tsc -b --watch"
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@
|
|
44
|
-
"@jupyterlab/
|
|
45
|
-
"@jupyterlab/
|
|
46
|
-
"@jupyterlab/
|
|
47
|
-
"@jupyterlab/
|
|
48
|
-
"@jupyterlab/
|
|
49
|
-
"@
|
|
50
|
-
"@lumino/
|
|
51
|
-
"@lumino/
|
|
52
|
-
"@lumino/
|
|
53
|
-
"@lumino/
|
|
43
|
+
"@jupyter/ydoc": "^0.3.4",
|
|
44
|
+
"@jupyterlab/apputils": "^4.0.0-beta.0",
|
|
45
|
+
"@jupyterlab/cells": "^4.0.0-beta.0",
|
|
46
|
+
"@jupyterlab/docregistry": "^4.0.0-beta.0",
|
|
47
|
+
"@jupyterlab/notebook": "^4.0.0-beta.0",
|
|
48
|
+
"@jupyterlab/observables": "^5.0.0-beta.0",
|
|
49
|
+
"@jupyterlab/ui-components": "^4.0.0-beta.0",
|
|
50
|
+
"@lumino/algorithm": "^2.0.0",
|
|
51
|
+
"@lumino/commands": "^2.0.0",
|
|
52
|
+
"@lumino/disposable": "^2.0.0",
|
|
53
|
+
"@lumino/signaling": "^2.0.0",
|
|
54
|
+
"@lumino/widgets": "^2.0.0"
|
|
54
55
|
},
|
|
55
56
|
"devDependencies": {
|
|
56
|
-
"@jupyterlab/
|
|
57
|
-
"@types/jest": "^
|
|
58
|
-
"jest": "^
|
|
57
|
+
"@jupyterlab/testing": "^4.0.0-beta.0",
|
|
58
|
+
"@types/jest": "^29.2.0",
|
|
59
|
+
"jest": "^29.2.0",
|
|
59
60
|
"rimraf": "~3.0.0",
|
|
60
|
-
"
|
|
61
|
-
"typescript": "~4.6.3"
|
|
61
|
+
"typescript": "~5.0.2"
|
|
62
62
|
},
|
|
63
63
|
"publishConfig": {
|
|
64
64
|
"access": "public"
|
|
@@ -0,0 +1,479 @@
|
|
|
1
|
+
/* -----------------------------------------------------------------------------
|
|
2
|
+
| Copyright (c) Jupyter Development Team.
|
|
3
|
+
| Distributed under the terms of the Modified BSD License.
|
|
4
|
+
|----------------------------------------------------------------------------*/
|
|
5
|
+
import { createDefaultFactory, ToolbarRegistry } from '@jupyterlab/apputils';
|
|
6
|
+
import {
|
|
7
|
+
Cell,
|
|
8
|
+
CellModel,
|
|
9
|
+
CodeCell,
|
|
10
|
+
ICellModel,
|
|
11
|
+
MarkdownCell
|
|
12
|
+
} from '@jupyterlab/cells';
|
|
13
|
+
import { DocumentRegistry } from '@jupyterlab/docregistry';
|
|
14
|
+
import { Notebook, NotebookPanel } from '@jupyterlab/notebook';
|
|
15
|
+
import { IObservableList, ObservableList } from '@jupyterlab/observables';
|
|
16
|
+
import { ReactWidget, Toolbar } from '@jupyterlab/ui-components';
|
|
17
|
+
import { some } from '@lumino/algorithm';
|
|
18
|
+
import { CommandRegistry } from '@lumino/commands';
|
|
19
|
+
import { IDisposable } from '@lumino/disposable';
|
|
20
|
+
import { Signal } from '@lumino/signaling';
|
|
21
|
+
import { PanelLayout, Widget } from '@lumino/widgets';
|
|
22
|
+
import { IMapChange } from '@jupyter/ydoc';
|
|
23
|
+
|
|
24
|
+
/*
|
|
25
|
+
* Text mime types
|
|
26
|
+
*/
|
|
27
|
+
const TEXT_MIME_TYPES = [
|
|
28
|
+
'text/plain',
|
|
29
|
+
'application/vnd.jupyter.stdout',
|
|
30
|
+
'application/vnd.jupyter.stderr'
|
|
31
|
+
];
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Widget cell toolbar classes
|
|
35
|
+
*/
|
|
36
|
+
const CELL_TOOLBAR_CLASS = 'jp-cell-toolbar';
|
|
37
|
+
const CELL_MENU_CLASS = 'jp-cell-menu';
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Class for a cell whose contents overlap with the cell toolbar
|
|
41
|
+
*/
|
|
42
|
+
const TOOLBAR_OVERLAP_CLASS = 'jp-toolbar-overlap';
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Watch a notebook so that a cell toolbar appears on the active cell
|
|
46
|
+
*/
|
|
47
|
+
export class CellToolbarTracker implements IDisposable {
|
|
48
|
+
constructor(
|
|
49
|
+
panel: NotebookPanel,
|
|
50
|
+
toolbar: IObservableList<ToolbarRegistry.IToolbarItem>
|
|
51
|
+
) {
|
|
52
|
+
this._panel = panel;
|
|
53
|
+
this._previousActiveCell = this._panel.content.activeCell;
|
|
54
|
+
this._toolbar = toolbar;
|
|
55
|
+
|
|
56
|
+
this._onToolbarChanged();
|
|
57
|
+
this._toolbar.changed.connect(this._onToolbarChanged, this);
|
|
58
|
+
|
|
59
|
+
// Only add the toolbar to the notebook's active cell (if any) once it has fully rendered and been revealed.
|
|
60
|
+
void panel.revealed.then(() => {
|
|
61
|
+
// Wait one frame (at 60 fps) for the panel to render the first cell, then display the cell toolbar on it if possible.
|
|
62
|
+
setTimeout(() => {
|
|
63
|
+
this._onActiveCellChanged(panel.content);
|
|
64
|
+
}, 1000 / 60);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
// Check whether the toolbar should be rendered upon a layout change
|
|
68
|
+
panel.content.renderingLayoutChanged.connect(
|
|
69
|
+
this._onActiveCellChanged,
|
|
70
|
+
this
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
// Handle subsequent changes of active cell.
|
|
74
|
+
panel.content.activeCellChanged.connect(this._onActiveCellChanged, this);
|
|
75
|
+
panel.content.activeCell?.model.metadataChanged.connect(
|
|
76
|
+
this._onMetadataChanged,
|
|
77
|
+
this
|
|
78
|
+
);
|
|
79
|
+
panel.disposed.connect(() => {
|
|
80
|
+
panel.content.activeCellChanged.disconnect(this._onActiveCellChanged);
|
|
81
|
+
panel.content.activeCell?.model.metadataChanged.disconnect(
|
|
82
|
+
this._onMetadataChanged
|
|
83
|
+
);
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
_onMetadataChanged(model: CellModel, args: IMapChange) {
|
|
88
|
+
if (args.key === 'jupyter') {
|
|
89
|
+
if (
|
|
90
|
+
typeof args.newValue === 'object' &&
|
|
91
|
+
args.newValue.source_hidden === true &&
|
|
92
|
+
(args.type === 'add' || args.type === 'change')
|
|
93
|
+
) {
|
|
94
|
+
// Cell just became hidden; remove toolbar
|
|
95
|
+
this._removeToolbar(model);
|
|
96
|
+
}
|
|
97
|
+
// Check whether input visibility changed
|
|
98
|
+
else if (
|
|
99
|
+
typeof args.oldValue === 'object' &&
|
|
100
|
+
args.oldValue.source_hidden === true
|
|
101
|
+
) {
|
|
102
|
+
// Cell just became visible; add toolbar
|
|
103
|
+
this._addToolbar(model);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
_onActiveCellChanged(notebook: Notebook): void {
|
|
108
|
+
if (this._previousActiveCell && !this._previousActiveCell.isDisposed) {
|
|
109
|
+
// Disposed cells do not have a model anymore.
|
|
110
|
+
this._removeToolbar(this._previousActiveCell.model);
|
|
111
|
+
this._previousActiveCell.model.metadataChanged.disconnect(
|
|
112
|
+
this._onMetadataChanged
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const activeCell = notebook.activeCell;
|
|
117
|
+
if (activeCell === null || activeCell.inputHidden) {
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
activeCell.model.metadataChanged.connect(this._onMetadataChanged, this);
|
|
122
|
+
|
|
123
|
+
this._addToolbar(activeCell.model);
|
|
124
|
+
this._previousActiveCell = activeCell;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
get isDisposed(): boolean {
|
|
128
|
+
return this._isDisposed;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
dispose(): void {
|
|
132
|
+
if (this.isDisposed) {
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
this._isDisposed = true;
|
|
136
|
+
|
|
137
|
+
this._toolbar.changed.disconnect(this._onToolbarChanged, this);
|
|
138
|
+
|
|
139
|
+
const cells = this._panel?.context.model.cells;
|
|
140
|
+
if (cells) {
|
|
141
|
+
for (const model of cells) {
|
|
142
|
+
this._removeToolbar(model);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
this._panel = null;
|
|
147
|
+
|
|
148
|
+
Signal.clearData(this);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
private _addToolbar(model: ICellModel): void {
|
|
152
|
+
const cell = this._getCell(model);
|
|
153
|
+
|
|
154
|
+
if (cell) {
|
|
155
|
+
const toolbarWidget = new Toolbar();
|
|
156
|
+
toolbarWidget.addClass(CELL_MENU_CLASS);
|
|
157
|
+
|
|
158
|
+
const promises: Promise<void>[] = [];
|
|
159
|
+
for (const { name, widget } of this._toolbar) {
|
|
160
|
+
toolbarWidget.addItem(name, widget);
|
|
161
|
+
if (
|
|
162
|
+
widget instanceof ReactWidget &&
|
|
163
|
+
(widget as ReactWidget).renderPromise !== undefined
|
|
164
|
+
) {
|
|
165
|
+
(widget as ReactWidget).update();
|
|
166
|
+
promises.push((widget as ReactWidget).renderPromise!);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// Wait for all the buttons to be rendered before attaching the toolbar.
|
|
171
|
+
Promise.all(promises)
|
|
172
|
+
.then(() => {
|
|
173
|
+
toolbarWidget.addClass(CELL_TOOLBAR_CLASS);
|
|
174
|
+
(cell.layout as PanelLayout).insertWidget(0, toolbarWidget);
|
|
175
|
+
|
|
176
|
+
// For rendered markdown, watch for resize events.
|
|
177
|
+
cell.displayChanged.connect(this._resizeEventCallback, this);
|
|
178
|
+
|
|
179
|
+
// Watch for changes in the cell's contents.
|
|
180
|
+
cell.model.contentChanged.connect(this._changedEventCallback, this);
|
|
181
|
+
|
|
182
|
+
// Hide the cell toolbar if it overlaps with cell contents
|
|
183
|
+
this._updateCellForToolbarOverlap(cell);
|
|
184
|
+
})
|
|
185
|
+
.catch(e => {
|
|
186
|
+
console.error('Error rendering buttons of the cell toolbar: ', e);
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
private _getCell(model: ICellModel): Cell | undefined {
|
|
192
|
+
return this._panel?.content.widgets.find(widget => widget.model === model);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
private _findToolbarWidgets(cell: Cell): Widget[] {
|
|
196
|
+
const widgets = (cell.layout as PanelLayout).widgets;
|
|
197
|
+
|
|
198
|
+
// Search for header using the CSS class or use the first one if not found.
|
|
199
|
+
return widgets.filter(widget => widget.hasClass(CELL_TOOLBAR_CLASS)) || [];
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
private _removeToolbar(model: ICellModel): void {
|
|
203
|
+
const cell = this._getCell(model);
|
|
204
|
+
if (cell) {
|
|
205
|
+
this._findToolbarWidgets(cell).forEach(widget => {
|
|
206
|
+
widget.dispose();
|
|
207
|
+
});
|
|
208
|
+
// Attempt to remove the resize and changed event handlers.
|
|
209
|
+
cell.displayChanged.disconnect(this._resizeEventCallback, this);
|
|
210
|
+
}
|
|
211
|
+
model.contentChanged.disconnect(this._changedEventCallback, this);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Call back on settings changes
|
|
216
|
+
*/
|
|
217
|
+
private _onToolbarChanged(): void {
|
|
218
|
+
// Reset toolbar when settings changes
|
|
219
|
+
const activeCell: Cell<ICellModel> | null | undefined =
|
|
220
|
+
this._panel?.content.activeCell;
|
|
221
|
+
if (activeCell) {
|
|
222
|
+
this._removeToolbar(activeCell.model);
|
|
223
|
+
this._addToolbar(activeCell.model);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
private _changedEventCallback(): void {
|
|
228
|
+
const activeCell = this._panel?.content.activeCell;
|
|
229
|
+
if (activeCell === null || activeCell === undefined) {
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
this._updateCellForToolbarOverlap(activeCell);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
private _resizeEventCallback(): void {
|
|
237
|
+
const activeCell = this._panel?.content.activeCell;
|
|
238
|
+
if (activeCell === null || activeCell === undefined) {
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
this._updateCellForToolbarOverlap(activeCell);
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
private _updateCellForToolbarOverlap(activeCell: Cell<ICellModel>) {
|
|
246
|
+
// Remove the "toolbar overlap" class from the cell, rendering the cell's toolbar
|
|
247
|
+
const activeCellElement = activeCell.node;
|
|
248
|
+
activeCellElement.classList.remove(TOOLBAR_OVERLAP_CLASS);
|
|
249
|
+
|
|
250
|
+
if (this._cellToolbarOverlapsContents(activeCell)) {
|
|
251
|
+
// Add the "toolbar overlap" class to the cell, completely concealing the toolbar,
|
|
252
|
+
// if the first line of the content overlaps with it at all
|
|
253
|
+
activeCellElement.classList.add(TOOLBAR_OVERLAP_CLASS);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
private _cellToolbarOverlapsContents(activeCell: Cell<ICellModel>): boolean {
|
|
258
|
+
const cellType = activeCell.model.type;
|
|
259
|
+
|
|
260
|
+
// If the toolbar is too large for the current cell, hide it.
|
|
261
|
+
const cellLeft = this._cellEditorWidgetLeft(activeCell);
|
|
262
|
+
const cellRight = this._cellEditorWidgetRight(activeCell);
|
|
263
|
+
const toolbarLeft = this._cellToolbarLeft(activeCell);
|
|
264
|
+
|
|
265
|
+
if (toolbarLeft === null) {
|
|
266
|
+
return false;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// The toolbar should not take up more than 50% of the cell.
|
|
270
|
+
if ((cellLeft + cellRight) / 2 > toolbarLeft) {
|
|
271
|
+
return true;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
if (cellType === 'markdown' && (activeCell as MarkdownCell).rendered) {
|
|
275
|
+
// Check for overlap in rendered markdown content
|
|
276
|
+
return this._markdownOverlapsToolbar(activeCell as MarkdownCell);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// Check for overlap in code content
|
|
280
|
+
if (this._panel?.content.renderingLayout === 'default') {
|
|
281
|
+
return this._codeOverlapsToolbar(activeCell);
|
|
282
|
+
} else {
|
|
283
|
+
return this._outputOverlapsToolbar(activeCell);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* Check for overlap between rendered Markdown and the cell toolbar
|
|
289
|
+
*
|
|
290
|
+
* @param activeCell A rendered MarkdownCell
|
|
291
|
+
* @returns `true` if the first line of the output overlaps with the cell toolbar, `false` otherwise
|
|
292
|
+
*/
|
|
293
|
+
private _markdownOverlapsToolbar(activeCell: MarkdownCell): boolean {
|
|
294
|
+
const markdownOutput = activeCell.inputArea; // Rendered markdown appears in the input area
|
|
295
|
+
if (!markdownOutput) {
|
|
296
|
+
return false;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
// Get the rendered markdown as a widget.
|
|
300
|
+
const markdownOutputWidget = markdownOutput.renderedInput;
|
|
301
|
+
const markdownOutputElement = markdownOutputWidget.node;
|
|
302
|
+
|
|
303
|
+
const firstOutputElementChild =
|
|
304
|
+
markdownOutputElement.firstElementChild as HTMLElement;
|
|
305
|
+
if (firstOutputElementChild === null) {
|
|
306
|
+
return false;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
// Temporarily set the element's max width so that the bounding client rectangle only encompasses the content.
|
|
310
|
+
const oldMaxWidth = firstOutputElementChild.style.maxWidth;
|
|
311
|
+
firstOutputElementChild.style.maxWidth = 'max-content';
|
|
312
|
+
|
|
313
|
+
const lineRight = firstOutputElementChild.getBoundingClientRect().right;
|
|
314
|
+
|
|
315
|
+
// Reinstate the old max width.
|
|
316
|
+
firstOutputElementChild.style.maxWidth = oldMaxWidth;
|
|
317
|
+
|
|
318
|
+
const toolbarLeft = this._cellToolbarLeft(activeCell);
|
|
319
|
+
|
|
320
|
+
return toolbarLeft === null ? false : lineRight > toolbarLeft;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
private _outputOverlapsToolbar(activeCell: Cell<ICellModel>): boolean {
|
|
324
|
+
const outputArea = (activeCell as CodeCell).outputArea.node;
|
|
325
|
+
if (outputArea) {
|
|
326
|
+
const outputs = outputArea.querySelectorAll('[data-mime-type]');
|
|
327
|
+
const toolbarRect = this._cellToolbarRect(activeCell);
|
|
328
|
+
if (toolbarRect) {
|
|
329
|
+
const { left: toolbarLeft, bottom: toolbarBottom } = toolbarRect;
|
|
330
|
+
return some(outputs, output => {
|
|
331
|
+
const node = output.firstElementChild;
|
|
332
|
+
if (node) {
|
|
333
|
+
const range = new Range();
|
|
334
|
+
if (
|
|
335
|
+
TEXT_MIME_TYPES.includes(
|
|
336
|
+
output.getAttribute('data-mime-type') || ''
|
|
337
|
+
)
|
|
338
|
+
) {
|
|
339
|
+
// If the node is plain text, it's in a <pre>. To get the true bounding box of the
|
|
340
|
+
// text, the node contents need to be selected.
|
|
341
|
+
range.selectNodeContents(node);
|
|
342
|
+
} else {
|
|
343
|
+
range.selectNode(node);
|
|
344
|
+
}
|
|
345
|
+
const { right: nodeRight, top: nodeTop } =
|
|
346
|
+
range.getBoundingClientRect();
|
|
347
|
+
|
|
348
|
+
// Note: y-coordinate increases toward the bottom of page
|
|
349
|
+
return nodeRight > toolbarLeft && nodeTop < toolbarBottom;
|
|
350
|
+
}
|
|
351
|
+
return false;
|
|
352
|
+
});
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
return false;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
private _codeOverlapsToolbar(activeCell: Cell<ICellModel>): boolean {
|
|
359
|
+
const editorWidget = activeCell.editorWidget;
|
|
360
|
+
const editor = activeCell.editor;
|
|
361
|
+
if (!editorWidget || !editor) {
|
|
362
|
+
return false;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
if (editor.lineCount < 1) {
|
|
366
|
+
return false; // Nothing in the editor
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
const codeMirrorLines = editorWidget.node.getElementsByClassName('cm-line');
|
|
370
|
+
if (codeMirrorLines.length < 1) {
|
|
371
|
+
return false; // No lines present
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
let lineRight = codeMirrorLines[0].getBoundingClientRect().left;
|
|
375
|
+
const range = document.createRange();
|
|
376
|
+
range.selectNodeContents(codeMirrorLines[0]);
|
|
377
|
+
lineRight += range.getBoundingClientRect().width;
|
|
378
|
+
|
|
379
|
+
const toolbarLeft = this._cellToolbarLeft(activeCell);
|
|
380
|
+
|
|
381
|
+
return toolbarLeft === null ? false : lineRight > toolbarLeft;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
private _cellEditorWidgetLeft(activeCell: Cell<ICellModel>): number {
|
|
385
|
+
return activeCell.editorWidget?.node.getBoundingClientRect().left ?? 0;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
private _cellEditorWidgetRight(activeCell: Cell<ICellModel>): number {
|
|
389
|
+
return activeCell.editorWidget?.node.getBoundingClientRect().right ?? 0;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
private _cellToolbarRect(activeCell: Cell<ICellModel>): DOMRect | null {
|
|
393
|
+
const toolbarWidgets = this._findToolbarWidgets(activeCell);
|
|
394
|
+
if (toolbarWidgets.length < 1) {
|
|
395
|
+
return null;
|
|
396
|
+
}
|
|
397
|
+
const activeCellToolbar = toolbarWidgets[0].node;
|
|
398
|
+
|
|
399
|
+
return activeCellToolbar.getBoundingClientRect();
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
private _cellToolbarLeft(activeCell: Cell<ICellModel>): number | null {
|
|
403
|
+
return this._cellToolbarRect(activeCell)?.left || null;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
private _isDisposed = false;
|
|
407
|
+
private _panel: NotebookPanel | null;
|
|
408
|
+
private _previousActiveCell: Cell<ICellModel> | null;
|
|
409
|
+
private _toolbar: IObservableList<ToolbarRegistry.IToolbarItem>;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
const defaultToolbarItems: ToolbarRegistry.IWidget[] = [
|
|
413
|
+
{
|
|
414
|
+
command: 'notebook:duplicate-below',
|
|
415
|
+
name: 'duplicate-cell'
|
|
416
|
+
},
|
|
417
|
+
{
|
|
418
|
+
command: 'notebook:move-cell-up',
|
|
419
|
+
name: 'move-cell-up'
|
|
420
|
+
},
|
|
421
|
+
{
|
|
422
|
+
command: 'notebook:move-cell-down',
|
|
423
|
+
name: 'move-cell-down'
|
|
424
|
+
},
|
|
425
|
+
{
|
|
426
|
+
command: 'notebook:insert-cell-above',
|
|
427
|
+
name: 'insert-cell-above'
|
|
428
|
+
},
|
|
429
|
+
{
|
|
430
|
+
command: 'notebook:insert-cell-below',
|
|
431
|
+
name: 'insert-cell-below'
|
|
432
|
+
},
|
|
433
|
+
{
|
|
434
|
+
command: 'notebook:delete-cell',
|
|
435
|
+
name: 'delete-cell'
|
|
436
|
+
}
|
|
437
|
+
];
|
|
438
|
+
|
|
439
|
+
/**
|
|
440
|
+
* Widget extension that creates a CellToolbarTracker each time a notebook is
|
|
441
|
+
* created.
|
|
442
|
+
*/
|
|
443
|
+
export class CellBarExtension implements DocumentRegistry.WidgetExtension {
|
|
444
|
+
static FACTORY_NAME = 'Cell';
|
|
445
|
+
|
|
446
|
+
constructor(
|
|
447
|
+
commands: CommandRegistry,
|
|
448
|
+
toolbarFactory?: (
|
|
449
|
+
widget: Widget
|
|
450
|
+
) => IObservableList<ToolbarRegistry.IToolbarItem>
|
|
451
|
+
) {
|
|
452
|
+
this._commands = commands;
|
|
453
|
+
this._toolbarFactory = toolbarFactory ?? this.defaultToolbarFactory;
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
protected get defaultToolbarFactory(): (
|
|
457
|
+
widget: Widget
|
|
458
|
+
) => IObservableList<ToolbarRegistry.IToolbarItem> {
|
|
459
|
+
const itemFactory = createDefaultFactory(this._commands);
|
|
460
|
+
return (widget: Widget) =>
|
|
461
|
+
new ObservableList({
|
|
462
|
+
values: defaultToolbarItems.map(item => {
|
|
463
|
+
return {
|
|
464
|
+
name: item.name,
|
|
465
|
+
widget: itemFactory(CellBarExtension.FACTORY_NAME, widget, item)
|
|
466
|
+
};
|
|
467
|
+
})
|
|
468
|
+
});
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
createNew(panel: NotebookPanel): IDisposable {
|
|
472
|
+
return new CellToolbarTracker(panel, this._toolbarFactory(panel));
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
private _commands: CommandRegistry;
|
|
476
|
+
private _toolbarFactory: (
|
|
477
|
+
widget: Widget
|
|
478
|
+
) => IObservableList<ToolbarRegistry.IToolbarItem>;
|
|
479
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/* -----------------------------------------------------------------------------
|
|
2
|
+
| Copyright (c) Jupyter Development Team.
|
|
3
|
+
| Distributed under the terms of the Modified BSD License.
|
|
4
|
+
|----------------------------------------------------------------------------*/
|
|
5
|
+
/**
|
|
6
|
+
* @packageDocumentation
|
|
7
|
+
* @module cell-toolbar
|
|
8
|
+
*/
|
|
9
|
+
export * from './celltoolbartracker';
|
package/style/base.css
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) Jupyter Development Team.
|
|
3
|
+
* Distributed under the terms of the Modified BSD License.
|
|
4
|
+
*/
|
|
5
|
+
|
|
1
6
|
.jp-cell-button .jp-icon3[fill] {
|
|
2
7
|
fill: var(--jp-inverse-layout-color4);
|
|
3
8
|
}
|
|
@@ -15,7 +20,7 @@
|
|
|
15
20
|
flex-direction: row;
|
|
16
21
|
padding: 2px 0;
|
|
17
22
|
min-height: 25px;
|
|
18
|
-
z-index:
|
|
23
|
+
z-index: 6;
|
|
19
24
|
position: absolute;
|
|
20
25
|
top: 5px;
|
|
21
26
|
right: 8px;
|
|
@@ -26,14 +31,10 @@
|
|
|
26
31
|
box-shadow: inherit;
|
|
27
32
|
}
|
|
28
33
|
|
|
29
|
-
/* Overrides for mobile view
|
|
34
|
+
/* Overrides for mobile view hiding cell toolbar */
|
|
30
35
|
@media only screen and (max-width: 760px) {
|
|
31
|
-
.jp-
|
|
32
|
-
display:
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
.jp-cell-toolbar {
|
|
36
|
-
top: -5px;
|
|
36
|
+
.jp-cell-menu.jp-cell-toolbar {
|
|
37
|
+
display: none;
|
|
37
38
|
}
|
|
38
39
|
}
|
|
39
40
|
|