@jupyter-notebook/notebook-extension 7.0.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/index.d.ts +6 -0
- package/lib/index.js +294 -0
- package/package.json +65 -0
- package/schema/scroll-output.json +16 -0
- package/style/base.css +138 -0
- package/style/index.css +1 -0
- package/style/index.js +1 -0
- package/style/variables.css +6 -0
package/lib/index.d.ts
ADDED
package/lib/index.js
ADDED
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
// Copyright (c) Jupyter Development Team.
|
|
2
|
+
// Distributed under the terms of the Modified BSD License.
|
|
3
|
+
import { DOMUtils } from '@jupyterlab/apputils';
|
|
4
|
+
import { Text, Time } from '@jupyterlab/coreutils';
|
|
5
|
+
import { IDocumentManager } from '@jupyterlab/docmanager';
|
|
6
|
+
import { IMainMenu } from '@jupyterlab/mainmenu';
|
|
7
|
+
import { NotebookPanel, INotebookTracker } from '@jupyterlab/notebook';
|
|
8
|
+
import { ISettingRegistry } from '@jupyterlab/settingregistry';
|
|
9
|
+
import { ITranslator } from '@jupyterlab/translation';
|
|
10
|
+
import { INotebookShell } from '@jupyter-notebook/application';
|
|
11
|
+
import { Poll } from '@lumino/polling';
|
|
12
|
+
import { Menu, Widget } from '@lumino/widgets';
|
|
13
|
+
/**
|
|
14
|
+
* The class for kernel status errors.
|
|
15
|
+
*/
|
|
16
|
+
const KERNEL_STATUS_ERROR_CLASS = 'jp-NotebookKernelStatus-error';
|
|
17
|
+
/**
|
|
18
|
+
* The class for kernel status warnings.
|
|
19
|
+
*/
|
|
20
|
+
const KERNEL_STATUS_WARN_CLASS = 'jp-NotebookKernelStatus-warn';
|
|
21
|
+
/**
|
|
22
|
+
* The class for kernel status infos.
|
|
23
|
+
*/
|
|
24
|
+
const KERNEL_STATUS_INFO_CLASS = 'jp-NotebookKernelStatus-info';
|
|
25
|
+
/**
|
|
26
|
+
* The class to fade out the kernel status.
|
|
27
|
+
*/
|
|
28
|
+
const KERNEL_STATUS_FADE_OUT_CLASS = 'jp-NotebookKernelStatus-fade';
|
|
29
|
+
/**
|
|
30
|
+
* The class for scrolled outputs
|
|
31
|
+
*/
|
|
32
|
+
const SCROLLED_OUTPUTS_CLASS = 'jp-mod-outputsScrolled';
|
|
33
|
+
/**
|
|
34
|
+
* A plugin for the checkpoint indicator
|
|
35
|
+
*/
|
|
36
|
+
const checkpoints = {
|
|
37
|
+
id: '@jupyter-notebook/notebook-extension:checkpoints',
|
|
38
|
+
autoStart: true,
|
|
39
|
+
requires: [IDocumentManager, ITranslator],
|
|
40
|
+
optional: [INotebookShell],
|
|
41
|
+
activate: (app, docManager, translator, notebookShell) => {
|
|
42
|
+
const { shell } = app;
|
|
43
|
+
const trans = translator.load('notebook');
|
|
44
|
+
const widget = new Widget();
|
|
45
|
+
widget.id = DOMUtils.createDomID();
|
|
46
|
+
widget.addClass('jp-NotebookCheckpoint');
|
|
47
|
+
app.shell.add(widget, 'top', { rank: 100 });
|
|
48
|
+
const onChange = async () => {
|
|
49
|
+
const current = shell.currentWidget;
|
|
50
|
+
if (!current) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
const context = docManager.contextForWidget(current);
|
|
54
|
+
context === null || context === void 0 ? void 0 : context.fileChanged.disconnect(onChange);
|
|
55
|
+
context === null || context === void 0 ? void 0 : context.fileChanged.connect(onChange);
|
|
56
|
+
const checkpoints = await (context === null || context === void 0 ? void 0 : context.listCheckpoints());
|
|
57
|
+
if (!checkpoints) {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
const checkpoint = checkpoints[checkpoints.length - 1];
|
|
61
|
+
widget.node.textContent = trans.__('Last Checkpoint: %1', Time.formatHuman(new Date(checkpoint.last_modified)));
|
|
62
|
+
};
|
|
63
|
+
if (notebookShell) {
|
|
64
|
+
notebookShell.currentChanged.connect(onChange);
|
|
65
|
+
}
|
|
66
|
+
new Poll({
|
|
67
|
+
auto: true,
|
|
68
|
+
factory: () => onChange(),
|
|
69
|
+
frequency: {
|
|
70
|
+
interval: 2000,
|
|
71
|
+
backoff: false
|
|
72
|
+
},
|
|
73
|
+
standby: 'when-hidden'
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
/**
|
|
78
|
+
* The kernel logo plugin.
|
|
79
|
+
*/
|
|
80
|
+
const kernelLogo = {
|
|
81
|
+
id: '@jupyter-notebook/notebook-extension:kernel-logo',
|
|
82
|
+
autoStart: true,
|
|
83
|
+
requires: [INotebookShell],
|
|
84
|
+
activate: (app, shell) => {
|
|
85
|
+
const { serviceManager } = app;
|
|
86
|
+
let widget;
|
|
87
|
+
const onChange = async () => {
|
|
88
|
+
var _a, _b, _c, _d, _e;
|
|
89
|
+
if (widget) {
|
|
90
|
+
widget.dispose();
|
|
91
|
+
widget.parent = null;
|
|
92
|
+
}
|
|
93
|
+
const current = shell.currentWidget;
|
|
94
|
+
if (!(current instanceof NotebookPanel)) {
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
await current.sessionContext.ready;
|
|
98
|
+
current.sessionContext.kernelChanged.disconnect(onChange);
|
|
99
|
+
current.sessionContext.kernelChanged.connect(onChange);
|
|
100
|
+
const name = (_c = (_b = (_a = current.sessionContext.session) === null || _a === void 0 ? void 0 : _a.kernel) === null || _b === void 0 ? void 0 : _b.name) !== null && _c !== void 0 ? _c : '';
|
|
101
|
+
const spec = (_e = (_d = serviceManager.kernelspecs) === null || _d === void 0 ? void 0 : _d.specs) === null || _e === void 0 ? void 0 : _e.kernelspecs[name];
|
|
102
|
+
if (!spec) {
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
const kernelIconUrl = spec.resources['logo-64x64'];
|
|
106
|
+
if (!kernelIconUrl) {
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
const node = document.createElement('div');
|
|
110
|
+
const img = document.createElement('img');
|
|
111
|
+
img.src = kernelIconUrl;
|
|
112
|
+
img.title = spec.display_name;
|
|
113
|
+
node.appendChild(img);
|
|
114
|
+
widget = new Widget({ node });
|
|
115
|
+
widget.addClass('jp-NotebookKernelLogo');
|
|
116
|
+
app.shell.add(widget, 'top', { rank: 10010 });
|
|
117
|
+
};
|
|
118
|
+
app.started.then(() => {
|
|
119
|
+
shell.currentChanged.connect(onChange);
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
/**
|
|
124
|
+
* A plugin to display the kernel status;
|
|
125
|
+
*/
|
|
126
|
+
const kernelStatus = {
|
|
127
|
+
id: '@jupyter-notebook/notebook-extension:kernel-status',
|
|
128
|
+
autoStart: true,
|
|
129
|
+
requires: [INotebookShell, ITranslator],
|
|
130
|
+
activate: (app, shell, translator) => {
|
|
131
|
+
const trans = translator.load('notebook');
|
|
132
|
+
const widget = new Widget();
|
|
133
|
+
widget.addClass('jp-NotebookKernelStatus');
|
|
134
|
+
app.shell.add(widget, 'menu', { rank: 10010 });
|
|
135
|
+
const removeClasses = () => {
|
|
136
|
+
widget.removeClass(KERNEL_STATUS_ERROR_CLASS);
|
|
137
|
+
widget.removeClass(KERNEL_STATUS_WARN_CLASS);
|
|
138
|
+
widget.removeClass(KERNEL_STATUS_INFO_CLASS);
|
|
139
|
+
widget.removeClass(KERNEL_STATUS_FADE_OUT_CLASS);
|
|
140
|
+
};
|
|
141
|
+
const onStatusChanged = (sessionContext) => {
|
|
142
|
+
const status = sessionContext.kernelDisplayStatus;
|
|
143
|
+
let text = `Kernel ${Text.titleCase(status)}`;
|
|
144
|
+
removeClasses();
|
|
145
|
+
switch (status) {
|
|
146
|
+
case 'busy':
|
|
147
|
+
case 'idle':
|
|
148
|
+
text = '';
|
|
149
|
+
widget.addClass(KERNEL_STATUS_FADE_OUT_CLASS);
|
|
150
|
+
break;
|
|
151
|
+
case 'dead':
|
|
152
|
+
case 'terminating':
|
|
153
|
+
widget.addClass(KERNEL_STATUS_ERROR_CLASS);
|
|
154
|
+
break;
|
|
155
|
+
case 'unknown':
|
|
156
|
+
widget.addClass(KERNEL_STATUS_WARN_CLASS);
|
|
157
|
+
break;
|
|
158
|
+
default:
|
|
159
|
+
widget.addClass(KERNEL_STATUS_INFO_CLASS);
|
|
160
|
+
widget.addClass(KERNEL_STATUS_FADE_OUT_CLASS);
|
|
161
|
+
break;
|
|
162
|
+
}
|
|
163
|
+
widget.node.textContent = trans.__(text);
|
|
164
|
+
};
|
|
165
|
+
const onChange = async () => {
|
|
166
|
+
const current = shell.currentWidget;
|
|
167
|
+
if (!(current instanceof NotebookPanel)) {
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
const sessionContext = current.sessionContext;
|
|
171
|
+
sessionContext.statusChanged.connect(onStatusChanged);
|
|
172
|
+
};
|
|
173
|
+
shell.currentChanged.connect(onChange);
|
|
174
|
+
}
|
|
175
|
+
};
|
|
176
|
+
/**
|
|
177
|
+
* A plugin to customize notebook related menu entries
|
|
178
|
+
* TODO: switch to settings define menus when fixed upstream: https://github.com/jupyterlab/jupyterlab/issues/11754
|
|
179
|
+
*/
|
|
180
|
+
const menuPlugin = {
|
|
181
|
+
id: '@jupyter-notebook/notebook-extension:menu-plugin',
|
|
182
|
+
autoStart: true,
|
|
183
|
+
requires: [IMainMenu, ITranslator],
|
|
184
|
+
activate: (app, mainMenu, translator) => {
|
|
185
|
+
const { commands } = app;
|
|
186
|
+
const trans = translator.load('notebook');
|
|
187
|
+
const cellTypeSubmenu = new Menu({ commands });
|
|
188
|
+
cellTypeSubmenu.title.label = trans._p('menu', 'Cell Type');
|
|
189
|
+
[
|
|
190
|
+
'notebook:change-cell-to-code',
|
|
191
|
+
'notebook:change-cell-to-markdown',
|
|
192
|
+
'notebook:change-cell-to-raw'
|
|
193
|
+
].forEach(command => {
|
|
194
|
+
cellTypeSubmenu.addItem({
|
|
195
|
+
command
|
|
196
|
+
});
|
|
197
|
+
});
|
|
198
|
+
mainMenu.runMenu.addItem({ type: 'separator', rank: 1000 });
|
|
199
|
+
mainMenu.runMenu.addItem({
|
|
200
|
+
type: 'submenu',
|
|
201
|
+
submenu: cellTypeSubmenu,
|
|
202
|
+
rank: 1010
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
};
|
|
206
|
+
/**
|
|
207
|
+
* A plugin to enable scrolling for outputs by default.
|
|
208
|
+
* Mimic the logic from the classic notebook, as found here:
|
|
209
|
+
* https://github.com/jupyter/notebook/blob/a9a31c096eeffe1bff4e9164c6a0442e0e13cdb3/notebook/static/notebook/js/outputarea.js#L96-L120
|
|
210
|
+
*/
|
|
211
|
+
const scrollOutput = {
|
|
212
|
+
id: '@jupyter-notebook/notebook-extension:scroll-output',
|
|
213
|
+
autoStart: true,
|
|
214
|
+
requires: [INotebookTracker],
|
|
215
|
+
optional: [ISettingRegistry],
|
|
216
|
+
activate: async (app, tracker, settingRegistry) => {
|
|
217
|
+
const autoScrollThreshold = 100;
|
|
218
|
+
let autoScrollOutputs = true;
|
|
219
|
+
// decide whether to scroll the output of the cell based on some heuristics
|
|
220
|
+
const autoScroll = (cell) => {
|
|
221
|
+
if (!autoScrollOutputs) {
|
|
222
|
+
// bail if disabled via the settings
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
const { outputArea } = cell;
|
|
226
|
+
// respect cells with an explicit scrolled state
|
|
227
|
+
const scrolled = cell.model.metadata.get('scrolled');
|
|
228
|
+
if (scrolled !== undefined) {
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
const { node } = outputArea;
|
|
232
|
+
const height = node.scrollHeight;
|
|
233
|
+
const fontSize = parseFloat(node.style.fontSize.replace('px', ''));
|
|
234
|
+
const lineHeight = (fontSize || 14) * 1.3;
|
|
235
|
+
// do not set via cell.outputScrolled = true, as this would
|
|
236
|
+
// otherwise synchronize the scrolled state to the notebook metadata
|
|
237
|
+
const scroll = height > lineHeight * autoScrollThreshold;
|
|
238
|
+
cell.toggleClass(SCROLLED_OUTPUTS_CLASS, scroll);
|
|
239
|
+
};
|
|
240
|
+
tracker.widgetAdded.connect((sender, notebook) => {
|
|
241
|
+
var _a;
|
|
242
|
+
(_a = notebook.model) === null || _a === void 0 ? void 0 : _a.cells.changed.connect((sender, changed) => {
|
|
243
|
+
// process new cells only
|
|
244
|
+
if (!(changed.type === 'add')) {
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
const [cellModel] = changed.newValues;
|
|
248
|
+
notebook.content.widgets.forEach(cell => {
|
|
249
|
+
if (cell.model.id === cellModel.id && cell.model.type === 'code') {
|
|
250
|
+
const codeCell = cell;
|
|
251
|
+
codeCell.outputArea.model.changed.connect(() => autoScroll(codeCell));
|
|
252
|
+
}
|
|
253
|
+
});
|
|
254
|
+
});
|
|
255
|
+
// when the notebook widget is created, process all the cells
|
|
256
|
+
// TODO: investigate why notebook.content.fullyRendered is not enough
|
|
257
|
+
notebook.sessionContext.ready.then(() => {
|
|
258
|
+
notebook.content.widgets.forEach(cell => {
|
|
259
|
+
if (cell.model.type === 'code') {
|
|
260
|
+
autoScroll(cell);
|
|
261
|
+
}
|
|
262
|
+
});
|
|
263
|
+
});
|
|
264
|
+
});
|
|
265
|
+
if (settingRegistry) {
|
|
266
|
+
const loadSettings = settingRegistry.load(scrollOutput.id);
|
|
267
|
+
const updateSettings = (settings) => {
|
|
268
|
+
autoScrollOutputs = settings.get('autoScrollOutputs')
|
|
269
|
+
.composite;
|
|
270
|
+
};
|
|
271
|
+
Promise.all([loadSettings, app.restored])
|
|
272
|
+
.then(([settings]) => {
|
|
273
|
+
updateSettings(settings);
|
|
274
|
+
settings.changed.connect(settings => {
|
|
275
|
+
updateSettings(settings);
|
|
276
|
+
});
|
|
277
|
+
})
|
|
278
|
+
.catch((reason) => {
|
|
279
|
+
console.error(reason.message);
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
};
|
|
284
|
+
/**
|
|
285
|
+
* Export the plugins as default.
|
|
286
|
+
*/
|
|
287
|
+
const plugins = [
|
|
288
|
+
checkpoints,
|
|
289
|
+
kernelLogo,
|
|
290
|
+
kernelStatus,
|
|
291
|
+
menuPlugin,
|
|
292
|
+
scrollOutput
|
|
293
|
+
];
|
|
294
|
+
export default plugins;
|
package/package.json
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@jupyter-notebook/notebook-extension",
|
|
3
|
+
"version": "7.0.0-alpha.1",
|
|
4
|
+
"description": "Jupyter Notebook - Notebook Extension",
|
|
5
|
+
"homepage": "https://github.com/jupyter/notebook",
|
|
6
|
+
"bugs": {
|
|
7
|
+
"url": "https://github.com/jupyter/notebook/issues"
|
|
8
|
+
},
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "https://github.com/jupyter/notebook.git"
|
|
12
|
+
},
|
|
13
|
+
"license": "BSD-3-Clause",
|
|
14
|
+
"author": "Project Jupyter",
|
|
15
|
+
"sideEffects": [
|
|
16
|
+
"style/**/*.css",
|
|
17
|
+
"style/index.js"
|
|
18
|
+
],
|
|
19
|
+
"main": "lib/index.js",
|
|
20
|
+
"types": "lib/index.d.ts",
|
|
21
|
+
"style": "style/index.css",
|
|
22
|
+
"directories": {
|
|
23
|
+
"lib": "lib/"
|
|
24
|
+
},
|
|
25
|
+
"files": [
|
|
26
|
+
"lib/*.d.ts",
|
|
27
|
+
"lib/*.js.map",
|
|
28
|
+
"lib/*.js",
|
|
29
|
+
"schema/*.json",
|
|
30
|
+
"style/**/*.css",
|
|
31
|
+
"style/index.js"
|
|
32
|
+
],
|
|
33
|
+
"scripts": {
|
|
34
|
+
"build": "tsc -b",
|
|
35
|
+
"build:prod": "tsc -b",
|
|
36
|
+
"clean": "rimraf lib && rimraf tsconfig.tsbuildinfo",
|
|
37
|
+
"docs": "typedoc src",
|
|
38
|
+
"prepublishOnly": "npm run build",
|
|
39
|
+
"watch": "tsc -b --watch"
|
|
40
|
+
},
|
|
41
|
+
"dependencies": {
|
|
42
|
+
"@jupyter-notebook/application": "^7.0.0-alpha.1",
|
|
43
|
+
"@jupyterlab/application": "^4.0.0-alpha.5",
|
|
44
|
+
"@jupyterlab/apputils": "^4.0.0-alpha.5",
|
|
45
|
+
"@jupyterlab/cells": "^4.0.0-alpha.5",
|
|
46
|
+
"@jupyterlab/docmanager": "^4.0.0-alpha.5",
|
|
47
|
+
"@jupyterlab/notebook": "^4.0.0-alpha.5",
|
|
48
|
+
"@jupyterlab/settingregistry": "^4.0.0-alpha.5",
|
|
49
|
+
"@jupyterlab/translation": "^4.0.0-alpha.4",
|
|
50
|
+
"@lumino/polling": "^1.10.0",
|
|
51
|
+
"@lumino/widgets": "^1.31.1"
|
|
52
|
+
},
|
|
53
|
+
"devDependencies": {
|
|
54
|
+
"rimraf": "~3.0.0",
|
|
55
|
+
"typescript": "~4.1.3"
|
|
56
|
+
},
|
|
57
|
+
"publishConfig": {
|
|
58
|
+
"access": "public"
|
|
59
|
+
},
|
|
60
|
+
"jupyterlab": {
|
|
61
|
+
"extension": true,
|
|
62
|
+
"schemaDir": "schema"
|
|
63
|
+
},
|
|
64
|
+
"styleModule": "style/index.js"
|
|
65
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"jupyter.lab.setting-icon": "notebook-ui-components:jupyter",
|
|
3
|
+
"jupyter.lab.setting-icon-label": "Jupyter Notebook Notebook",
|
|
4
|
+
"title": "Jupyter Notebook Notebook",
|
|
5
|
+
"description": "Jupyter Notebook Notebook settings",
|
|
6
|
+
"properties": {
|
|
7
|
+
"autoScrollOutputs": {
|
|
8
|
+
"type": "boolean",
|
|
9
|
+
"title": "Auto Scroll Outputs",
|
|
10
|
+
"description": "Whether to auto scroll the output area when the outputs become too long",
|
|
11
|
+
"default": true
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"additionalProperties": false,
|
|
15
|
+
"type": "object"
|
|
16
|
+
}
|
package/style/base.css
ADDED
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
/*-----------------------------------------------------------------------------
|
|
2
|
+
| Copyright (c) Jupyter Development Team.
|
|
3
|
+
|
|
|
4
|
+
| Distributed under the terms of the Modified BSD License.
|
|
5
|
+
|----------------------------------------------------------------------------*/
|
|
6
|
+
|
|
7
|
+
@import './variables.css';
|
|
8
|
+
|
|
9
|
+
/* Document oriented look for the notebook (scrollbar to the right of the page) */
|
|
10
|
+
|
|
11
|
+
body[data-notebook='notebooks'] .jp-NotebookPanel-toolbar {
|
|
12
|
+
padding-left: calc(calc(100% - var(--jp-notebook-max-width)) * 0.5);
|
|
13
|
+
padding-right: calc(calc(100% - var(--jp-notebook-max-width)) * 0.5);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
body[data-notebook='notebooks'] .jp-Notebook > * {
|
|
17
|
+
background: var(--jp-layout-color0);
|
|
18
|
+
padding: var(--jp-notebook-padding);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
body[data-notebook='notebooks']
|
|
22
|
+
.jp-Notebook.jp-mod-commandMode
|
|
23
|
+
.jp-Cell.jp-mod-active.jp-mod-selected:not(.jp-mod-multiSelected) {
|
|
24
|
+
background: var(--jp-layout-color0) !important;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
body[data-notebook='notebooks'] .jp-Notebook > *:first-child {
|
|
28
|
+
padding-top: var(--jp-notebook-padding-offset);
|
|
29
|
+
margin-top: var(--jp-notebook-toolbar-margin-bottom);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
body[data-notebook='notebooks'] .jp-Notebook {
|
|
33
|
+
padding-top: unset;
|
|
34
|
+
padding-bottom: unset;
|
|
35
|
+
padding-left: calc(calc(100% - var(--jp-notebook-max-width)) * 0.5);
|
|
36
|
+
padding-right: calc(
|
|
37
|
+
calc(
|
|
38
|
+
100% - var(--jp-notebook-max-width) - var(--jp-notebook-padding-offset)
|
|
39
|
+
) * 0.5
|
|
40
|
+
);
|
|
41
|
+
background: var(--jp-layout-color2);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
body[data-notebook='notebooks'] .jp-Notebook.jp-mod-scrollPastEnd::after {
|
|
45
|
+
background: var(--jp-layout-color0);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/* ---- */
|
|
49
|
+
|
|
50
|
+
.jp-NotebookKernelLogo {
|
|
51
|
+
flex: 0 0 auto;
|
|
52
|
+
display: flex;
|
|
53
|
+
align-items: center;
|
|
54
|
+
text-align: center;
|
|
55
|
+
margin-right: 8px;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.jp-NotebookKernelLogo img {
|
|
59
|
+
max-width: 28px;
|
|
60
|
+
max-height: 28px;
|
|
61
|
+
display: flex;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.jp-NotebookKernelStatus {
|
|
65
|
+
margin: 0;
|
|
66
|
+
font-weight: normal;
|
|
67
|
+
font-size: var(--jp-ui-font-size1);
|
|
68
|
+
color: var(--jp-ui-font-color0);
|
|
69
|
+
font-family: var(--jp-ui-font-family);
|
|
70
|
+
line-height: var(--jp-private-title-panel-height);
|
|
71
|
+
padding-left: var(--jp-kernel-status-padding);
|
|
72
|
+
padding-right: var(--jp-kernel-status-padding);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.jp-NotebookKernelStatus-error {
|
|
76
|
+
background-color: var(--jp-error-color0);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.jp-NotebookKernelStatus-warn {
|
|
80
|
+
background-color: var(--jp-warn-color0);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.jp-NotebookKernelStatus-info {
|
|
84
|
+
background-color: var(--jp-info-color0);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
.jp-NotebookKernelStatus-fade {
|
|
88
|
+
animation: 0.5s fade-out forwards;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
@keyframes fade-out {
|
|
92
|
+
0% {
|
|
93
|
+
opacity: 1;
|
|
94
|
+
}
|
|
95
|
+
100% {
|
|
96
|
+
opacity: 0;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
#jp-title h1 {
|
|
101
|
+
cursor: pointer;
|
|
102
|
+
font-size: 18px;
|
|
103
|
+
margin: 0;
|
|
104
|
+
font-weight: normal;
|
|
105
|
+
color: var(--jp-ui-font-color0);
|
|
106
|
+
font-family: var(--jp-ui-font-family);
|
|
107
|
+
line-height: calc(1.5 * var(--jp-private-title-panel-height));
|
|
108
|
+
text-overflow: ellipsis;
|
|
109
|
+
overflow: hidden;
|
|
110
|
+
white-space: nowrap;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
#jp-title h1:hover {
|
|
114
|
+
background: var(--jp-layout-color2);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
.jp-NotebookCheckpoint {
|
|
118
|
+
font-size: 14px;
|
|
119
|
+
margin-left: 5px;
|
|
120
|
+
margin-right: 5px;
|
|
121
|
+
font-weight: normal;
|
|
122
|
+
color: var(--jp-ui-font-color0);
|
|
123
|
+
font-family: var(--jp-ui-font-family);
|
|
124
|
+
line-height: calc(1.5 * var(--jp-private-title-panel-height));
|
|
125
|
+
text-overflow: ellipsis;
|
|
126
|
+
overflow: hidden;
|
|
127
|
+
white-space: nowrap;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/* Mobile View */
|
|
131
|
+
|
|
132
|
+
body[data-format='mobile'] .jp-NotebookCheckpoint {
|
|
133
|
+
display: none;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
body[data-format='mobile'] .jp-Notebook > *:first-child {
|
|
137
|
+
margin-top: 0;
|
|
138
|
+
}
|
package/style/index.css
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@import url('./base.css');
|
package/style/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import './base.css';
|