@jupyter-notebook/notebook-extension 7.0.0-alpha.9 → 7.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/index.js CHANGED
@@ -1,14 +1,15 @@
1
1
  // Copyright (c) Jupyter Development Team.
2
2
  // Distributed under the terms of the Modified BSD License.
3
- import { DOMUtils, IToolbarWidgetRegistry } from '@jupyterlab/apputils';
3
+ import { DOMUtils, IToolbarWidgetRegistry, } from '@jupyterlab/apputils';
4
4
  import { Text, Time } from '@jupyterlab/coreutils';
5
5
  import { IDocumentManager } from '@jupyterlab/docmanager';
6
- import { NotebookPanel, INotebookTracker, INotebookTools } from '@jupyterlab/notebook';
6
+ import { NotebookPanel, INotebookTracker, INotebookTools, } from '@jupyterlab/notebook';
7
7
  import { ISettingRegistry } from '@jupyterlab/settingregistry';
8
8
  import { ITranslator } from '@jupyterlab/translation';
9
9
  import { INotebookShell } from '@jupyter-notebook/application';
10
10
  import { Poll } from '@lumino/polling';
11
11
  import { Widget } from '@lumino/widgets';
12
+ import { TrustedComponent } from './trusted';
12
13
  /**
13
14
  * The class for kernel status errors.
14
15
  */
@@ -42,7 +43,7 @@ const checkpoints = {
42
43
  const trans = translator.load('notebook');
43
44
  const node = document.createElement('div');
44
45
  if (toolbarRegistry) {
45
- toolbarRegistry.addFactory('TopBar', 'checkpoint', toolbar => {
46
+ toolbarRegistry.addFactory('TopBar', 'checkpoint', (toolbar) => {
46
47
  const widget = new Widget({ node });
47
48
  widget.id = DOMUtils.createDomID();
48
49
  widget.addClass('jp-NotebookCheckpoint');
@@ -72,11 +73,11 @@ const checkpoints = {
72
73
  factory: () => onChange(),
73
74
  frequency: {
74
75
  interval: 2000,
75
- backoff: false
76
+ backoff: false,
76
77
  },
77
- standby: 'when-hidden'
78
+ standby: 'when-hidden',
78
79
  });
79
- }
80
+ },
80
81
  };
81
82
  /**
82
83
  * The kernel logo plugin.
@@ -90,30 +91,34 @@ const kernelLogo = {
90
91
  const { serviceManager } = app;
91
92
  const node = document.createElement('div');
92
93
  const img = document.createElement('img');
93
- node.appendChild(img);
94
94
  const onChange = async () => {
95
95
  var _a, _b, _c, _d, _e;
96
96
  const current = shell.currentWidget;
97
97
  if (!(current instanceof NotebookPanel)) {
98
98
  return;
99
99
  }
100
+ if (!node.hasChildNodes()) {
101
+ node.appendChild(img);
102
+ }
100
103
  await current.sessionContext.ready;
101
104
  current.sessionContext.kernelChanged.disconnect(onChange);
102
105
  current.sessionContext.kernelChanged.connect(onChange);
103
106
  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 : '';
104
107
  const spec = (_e = (_d = serviceManager.kernelspecs) === null || _d === void 0 ? void 0 : _d.specs) === null || _e === void 0 ? void 0 : _e.kernelspecs[name];
105
108
  if (!spec) {
109
+ node.childNodes[0].remove();
106
110
  return;
107
111
  }
108
112
  const kernelIconUrl = spec.resources['logo-64x64'];
109
113
  if (!kernelIconUrl) {
114
+ node.childNodes[0].remove();
110
115
  return;
111
116
  }
112
117
  img.src = kernelIconUrl;
113
118
  img.title = spec.display_name;
114
119
  };
115
120
  if (toolbarRegistry) {
116
- toolbarRegistry.addFactory('TopBar', 'kernelLogo', toolbar => {
121
+ toolbarRegistry.addFactory('TopBar', 'kernelLogo', (toolbar) => {
117
122
  const widget = new Widget({ node });
118
123
  widget.addClass('jp-NotebookKernelLogo');
119
124
  return widget;
@@ -122,7 +127,7 @@ const kernelLogo = {
122
127
  app.started.then(() => {
123
128
  shell.currentChanged.connect(onChange);
124
129
  });
125
- }
130
+ },
126
131
  };
127
132
  /**
128
133
  * A plugin to display the kernel status;
@@ -175,7 +180,7 @@ const kernelStatus = {
175
180
  sessionContext.statusChanged.connect(onStatusChanged);
176
181
  };
177
182
  shell.currentChanged.connect(onChange);
178
- }
183
+ },
179
184
  };
180
185
  /**
181
186
  * A plugin to enable scrolling for outputs by default.
@@ -243,7 +248,7 @@ const scrollOutput = {
243
248
  Promise.all([loadSettings, app.restored])
244
249
  .then(([settings]) => {
245
250
  updateSettings(settings);
246
- settings.changed.connect(settings => {
251
+ settings.changed.connect((settings) => {
247
252
  updateSettings(settings);
248
253
  });
249
254
  })
@@ -251,7 +256,7 @@ const scrollOutput = {
251
256
  console.error(reason.message);
252
257
  });
253
258
  }
254
- }
259
+ },
255
260
  };
256
261
  /**
257
262
  * A plugin to add the NotebookTools to the side panel;
@@ -273,7 +278,28 @@ const notebookToolsWidget = {
273
278
  }
274
279
  };
275
280
  shell.currentChanged.connect(onChange);
276
- }
281
+ },
282
+ };
283
+ /**
284
+ * A plugin that adds a Trusted indicator to the menu area
285
+ */
286
+ const trusted = {
287
+ id: '@jupyter-notebook/notebook-extension:trusted',
288
+ autoStart: true,
289
+ requires: [INotebookShell, ITranslator],
290
+ activate: (app, notebookShell, translator) => {
291
+ const onChange = async () => {
292
+ const current = notebookShell.currentWidget;
293
+ if (!(current instanceof NotebookPanel)) {
294
+ return;
295
+ }
296
+ const notebook = current.content;
297
+ await current.context.ready;
298
+ const widget = TrustedComponent.create({ notebook, translator });
299
+ notebookShell.add(widget, 'menu', { rank: 11000 });
300
+ };
301
+ notebookShell.currentChanged.connect(onChange);
302
+ },
277
303
  };
278
304
  /**
279
305
  * Export the plugins as default.
@@ -283,6 +309,7 @@ const plugins = [
283
309
  kernelLogo,
284
310
  kernelStatus,
285
311
  scrollOutput,
286
- notebookToolsWidget
312
+ notebookToolsWidget,
313
+ trusted,
287
314
  ];
288
315
  export default plugins;
@@ -0,0 +1,18 @@
1
+ import { ReactWidget } from '@jupyterlab/apputils';
2
+ import { Notebook } from '@jupyterlab/notebook';
3
+ import { ITranslator } from '@jupyterlab/translation';
4
+ /**
5
+ * A namespace for TrustedComponent statics.
6
+ */
7
+ export declare namespace TrustedComponent {
8
+ /**
9
+ * Create a new TrustedComponent
10
+ *
11
+ * @param notebook The notebook
12
+ * @param translator The translator
13
+ */
14
+ const create: ({ notebook, translator, }: {
15
+ notebook: Notebook;
16
+ translator: ITranslator;
17
+ }) => ReactWidget;
18
+ }
package/lib/trusted.js ADDED
@@ -0,0 +1,69 @@
1
+ import { ReactWidget } from '@jupyterlab/apputils';
2
+ import { NotebookActions } from '@jupyterlab/notebook';
3
+ import React, { useEffect, useState } from 'react';
4
+ /**
5
+ * Check if a notebook is trusted
6
+ * @param notebook The notebook to check
7
+ * @returns true if the notebook is trusted, false otherwise
8
+ */
9
+ const isTrusted = (notebook) => {
10
+ const model = notebook.model;
11
+ if (!model) {
12
+ return false;
13
+ }
14
+ const cells = Array.from(model.cells);
15
+ const trusted = cells.reduce((accum, current) => {
16
+ if (current.trusted) {
17
+ return accum + 1;
18
+ }
19
+ else {
20
+ return accum;
21
+ }
22
+ }, 0);
23
+ const total = cells.length;
24
+ return trusted === total;
25
+ };
26
+ /**
27
+ * A React component to display the Trusted badge in the menu bar.
28
+ * @param notebook The Notebook
29
+ * @param translator The Translation service
30
+ */
31
+ const TrustedButton = ({ notebook, translator, }) => {
32
+ const trans = translator.load('notebook');
33
+ const [trusted, setTrusted] = useState(isTrusted(notebook));
34
+ const checkTrust = () => {
35
+ const v = isTrusted(notebook);
36
+ setTrusted(v);
37
+ };
38
+ const trust = async () => {
39
+ await NotebookActions.trust(notebook, translator);
40
+ checkTrust();
41
+ };
42
+ useEffect(() => {
43
+ notebook.modelContentChanged.connect(checkTrust);
44
+ notebook.activeCellChanged.connect(checkTrust);
45
+ checkTrust();
46
+ return () => {
47
+ notebook.modelContentChanged.disconnect(checkTrust);
48
+ notebook.activeCellChanged.disconnect(checkTrust);
49
+ };
50
+ });
51
+ return (React.createElement("button", { className: 'jp-NotebookTrustedStatus', style: !trusted ? { cursor: 'pointer' } : { cursor: 'help' }, onClick: () => !trusted && trust(), title: trusted
52
+ ? trans.__('JavaScript enabled for notebook display')
53
+ : trans.__('JavaScript disabled for notebook display') }, trusted ? trans.__('Trusted') : trans.__('Not Trusted')));
54
+ };
55
+ /**
56
+ * A namespace for TrustedComponent statics.
57
+ */
58
+ export var TrustedComponent;
59
+ (function (TrustedComponent) {
60
+ /**
61
+ * Create a new TrustedComponent
62
+ *
63
+ * @param notebook The notebook
64
+ * @param translator The translator
65
+ */
66
+ TrustedComponent.create = ({ notebook, translator, }) => {
67
+ return ReactWidget.create(React.createElement(TrustedButton, { notebook: notebook, translator: translator }));
68
+ };
69
+ })(TrustedComponent || (TrustedComponent = {}));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jupyter-notebook/notebook-extension",
3
- "version": "7.0.0-alpha.9",
3
+ "version": "7.0.0-beta.0",
4
4
  "description": "Jupyter Notebook - Notebook Extension",
5
5
  "homepage": "https://github.com/jupyter/notebook",
6
6
  "bugs": {
@@ -35,24 +35,23 @@
35
35
  "build:prod": "tsc -b",
36
36
  "clean": "rimraf lib && rimraf tsconfig.tsbuildinfo",
37
37
  "docs": "typedoc src",
38
- "prepublishOnly": "npm run build",
39
38
  "watch": "tsc -b --watch"
40
39
  },
41
40
  "dependencies": {
42
- "@jupyter-notebook/application": "^7.0.0-alpha.9",
43
- "@jupyterlab/application": "^4.0.0-alpha.16",
44
- "@jupyterlab/apputils": "^4.0.0-alpha.16",
45
- "@jupyterlab/cells": "^4.0.0-alpha.16",
46
- "@jupyterlab/docmanager": "^4.0.0-alpha.16",
47
- "@jupyterlab/notebook": "^4.0.0-alpha.16",
48
- "@jupyterlab/settingregistry": "^4.0.0-alpha.16",
49
- "@jupyterlab/translation": "^4.0.0-alpha.16",
50
- "@lumino/polling": "^2.0.0-alpha.6",
51
- "@lumino/widgets": "^2.0.0-alpha.6"
41
+ "@jupyter-notebook/application": "^7.0.0-beta.0",
42
+ "@jupyterlab/application": "^4.0.0-beta.0",
43
+ "@jupyterlab/apputils": "^4.0.0-beta.0",
44
+ "@jupyterlab/cells": "^4.0.0-beta.0",
45
+ "@jupyterlab/docmanager": "^4.0.0-beta.0",
46
+ "@jupyterlab/notebook": "^4.0.0-beta.0",
47
+ "@jupyterlab/settingregistry": "^4.0.0-beta.0",
48
+ "@jupyterlab/translation": "^4.0.0-beta.0",
49
+ "@lumino/polling": "^2.0.0",
50
+ "@lumino/widgets": "^2.0.1"
52
51
  },
53
52
  "devDependencies": {
54
53
  "rimraf": "^3.0.2",
55
- "typescript": "~4.7.3"
54
+ "typescript": "~5.0.2"
56
55
  },
57
56
  "publishConfig": {
58
57
  "access": "public"
package/style/base.css CHANGED
@@ -132,6 +132,10 @@ body[data-format='mobile'] .jp-Notebook > *:first-child {
132
132
  margin-top: 0;
133
133
  }
134
134
 
135
+ body[data-format='mobile'] .jp-ToolbarButton .jp-DebuggerBugButton {
136
+ display: none;
137
+ }
138
+
135
139
  /* Virtual Notebook fixes */
136
140
 
137
141
  body[data-notebook='notebooks'] .jp-WindowedPanel-window {
@@ -216,6 +220,19 @@ body[data-notebook='notebooks']
216
220
  animation: 0.5s fade-out forwards;
217
221
  }
218
222
 
223
+ .jp-NotebookTrustedStatus {
224
+ background: var(--jp-layout-color1);
225
+ color: var(--jp-ui-font-color1);
226
+ margin-top: 4px;
227
+ margin-bottom: 4px;
228
+ border: solid 1px var(--jp-border-color2);
229
+ cursor: help;
230
+ }
231
+
232
+ .jp-NotebookTrustedStatus-not-trusted {
233
+ cursor: pointer;
234
+ }
235
+
219
236
  @keyframes fade-out {
220
237
  0% {
221
238
  opacity: 1;