@jupyterlab/toc-extension 6.0.0-alpha.19 → 6.0.0-alpha.20

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 CHANGED
@@ -2,10 +2,10 @@
2
2
  * @packageDocumentation
3
3
  * @module toc-extension
4
4
  */
5
- import { JupyterFrontEnd, JupyterFrontEndPlugin } from '@jupyterlab/application';
5
+ import { JupyterFrontEndPlugin } from '@jupyterlab/application';
6
6
  import { ITableOfContentsRegistry, ITableOfContentsTracker } from '@jupyterlab/toc';
7
7
  /**
8
8
  * Exports.
9
9
  */
10
- declare const _default: (JupyterFrontEndPlugin<ITableOfContentsRegistry, JupyterFrontEnd.IShell, "desktop" | "mobile"> | JupyterFrontEndPlugin<ITableOfContentsTracker, JupyterFrontEnd.IShell, "desktop" | "mobile">)[];
10
+ declare const _default: (JupyterFrontEndPlugin<ITableOfContentsRegistry> | JupyterFrontEndPlugin<ITableOfContentsTracker>)[];
11
11
  export default _default;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jupyterlab/toc-extension",
3
- "version": "6.0.0-alpha.19",
3
+ "version": "6.0.0-alpha.20",
4
4
  "description": "JupyterLab - Table of Contents widget extension",
5
5
  "keywords": [
6
6
  "jupyter",
@@ -31,7 +31,8 @@
31
31
  "lib/**/*.{d.ts,eot,gif,html,jpg,js,js.map,json,png,svg,woff2,ttf}",
32
32
  "schema/*.json",
33
33
  "style/**/*.{css,eot,gif,html,jpg,json,png,svg,woff2,ttf}",
34
- "style/index.js"
34
+ "style/index.js",
35
+ "src/**/*.{ts,tsx}"
35
36
  ],
36
37
  "scripts": {
37
38
  "build": "tsc -b",
@@ -40,16 +41,16 @@
40
41
  "watch": "tsc -b --watch"
41
42
  },
42
43
  "dependencies": {
43
- "@jupyterlab/application": "^4.0.0-alpha.19",
44
- "@jupyterlab/settingregistry": "^4.0.0-alpha.19",
45
- "@jupyterlab/toc": "^6.0.0-alpha.19",
46
- "@jupyterlab/translation": "^4.0.0-alpha.19",
47
- "@jupyterlab/ui-components": "^4.0.0-alpha.34"
44
+ "@jupyterlab/application": "^4.0.0-alpha.20",
45
+ "@jupyterlab/settingregistry": "^4.0.0-alpha.20",
46
+ "@jupyterlab/toc": "^6.0.0-alpha.20",
47
+ "@jupyterlab/translation": "^4.0.0-alpha.20",
48
+ "@jupyterlab/ui-components": "^4.0.0-alpha.35"
48
49
  },
49
50
  "devDependencies": {
50
51
  "rimraf": "~3.0.0",
51
- "typedoc": "~0.22.10",
52
- "typescript": "~4.7.3"
52
+ "typedoc": "~0.23.25",
53
+ "typescript": "~5.0.0-beta"
53
54
  },
54
55
  "publishConfig": {
55
56
  "access": "public"
package/src/index.ts ADDED
@@ -0,0 +1,340 @@
1
+ // Copyright (c) Jupyter Development Team.
2
+ // Distributed under the terms of the Modified BSD License.
3
+ /**
4
+ * @packageDocumentation
5
+ * @module toc-extension
6
+ */
7
+
8
+ import {
9
+ ILabShell,
10
+ ILayoutRestorer,
11
+ JupyterFrontEnd,
12
+ JupyterFrontEndPlugin
13
+ } from '@jupyterlab/application';
14
+ import { ISettingRegistry } from '@jupyterlab/settingregistry';
15
+ import {
16
+ ITableOfContentsRegistry,
17
+ ITableOfContentsTracker,
18
+ TableOfContents,
19
+ TableOfContentsPanel,
20
+ TableOfContentsRegistry,
21
+ TableOfContentsTracker
22
+ } from '@jupyterlab/toc';
23
+ import { ITranslator, nullTranslator } from '@jupyterlab/translation';
24
+ import {
25
+ collapseAllIcon,
26
+ CommandToolbarButton,
27
+ ellipsesIcon,
28
+ expandAllIcon,
29
+ MenuSvg,
30
+ numberingIcon,
31
+ tocIcon,
32
+ Toolbar,
33
+ ToolbarButton
34
+ } from '@jupyterlab/ui-components';
35
+
36
+ /**
37
+ * A namespace for command IDs of table of contents plugin.
38
+ */
39
+ namespace CommandIDs {
40
+ export const displayNumbering = 'toc:display-numbering';
41
+
42
+ export const displayH1Numbering = 'toc:display-h1-numbering';
43
+
44
+ export const displayOutputNumbering = 'toc:display-outputs-numbering';
45
+
46
+ export const showPanel = 'toc:show-panel';
47
+
48
+ export const toggleCollapse = 'toc:toggle-collapse';
49
+ }
50
+
51
+ /**
52
+ * Activates the ToC extension.
53
+ *
54
+ * @private
55
+ * @param app - Jupyter application
56
+ * @param tocRegistry - Table of contents registry
57
+ * @param translator - translator
58
+ * @param restorer - application layout restorer
59
+ * @param labShell - Jupyter lab shell
60
+ * @param settingRegistry - setting registry
61
+ * @returns table of contents registry
62
+ */
63
+ async function activateTOC(
64
+ app: JupyterFrontEnd,
65
+ tocRegistry: ITableOfContentsRegistry,
66
+ translator?: ITranslator | null,
67
+ restorer?: ILayoutRestorer | null,
68
+ labShell?: ILabShell | null,
69
+ settingRegistry?: ISettingRegistry | null
70
+ ): Promise<ITableOfContentsTracker> {
71
+ const trans = (translator ?? nullTranslator).load('jupyterlab');
72
+ let configuration = { ...TableOfContents.defaultConfig };
73
+
74
+ // Create the ToC widget:
75
+ const toc = new TableOfContentsPanel(translator ?? undefined);
76
+ toc.title.icon = tocIcon;
77
+ toc.title.caption = trans.__('Table of Contents');
78
+ toc.id = 'table-of-contents';
79
+ toc.node.setAttribute('role', 'region');
80
+ toc.node.setAttribute('aria-label', trans.__('Table of Contents section'));
81
+
82
+ app.commands.addCommand(CommandIDs.displayH1Numbering, {
83
+ label: trans.__('Show first-level heading number'),
84
+ execute: () => {
85
+ if (toc.model) {
86
+ toc.model.setConfiguration({
87
+ numberingH1: !toc.model.configuration.numberingH1
88
+ });
89
+ }
90
+ },
91
+ isEnabled: () =>
92
+ toc.model?.supportedOptions.includes('numberingH1') ?? false,
93
+ isToggled: () => toc.model?.configuration.numberingH1 ?? false
94
+ });
95
+
96
+ app.commands.addCommand(CommandIDs.displayNumbering, {
97
+ label: trans.__('Show heading number in the document'),
98
+ icon: args => (args.toolbar ? numberingIcon : undefined),
99
+ execute: () => {
100
+ if (toc.model) {
101
+ toc.model.setConfiguration({
102
+ numberHeaders: !toc.model.configuration.numberHeaders
103
+ });
104
+ app.commands.notifyCommandChanged(CommandIDs.displayNumbering);
105
+ }
106
+ },
107
+ isEnabled: () =>
108
+ toc.model?.supportedOptions.includes('numberHeaders') ?? false,
109
+ isToggled: () => toc.model?.configuration.numberHeaders ?? false
110
+ });
111
+
112
+ app.commands.addCommand(CommandIDs.displayOutputNumbering, {
113
+ label: trans.__('Show output headings'),
114
+ execute: () => {
115
+ if (toc.model) {
116
+ toc.model.setConfiguration({
117
+ includeOutput: !toc.model.configuration.includeOutput
118
+ });
119
+ }
120
+ },
121
+ isEnabled: () =>
122
+ toc.model?.supportedOptions.includes('includeOutput') ?? false,
123
+ isToggled: () => toc.model?.configuration.includeOutput ?? false
124
+ });
125
+
126
+ app.commands.addCommand(CommandIDs.showPanel, {
127
+ label: trans.__('Table of Contents'),
128
+ execute: () => {
129
+ app.shell.activateById(toc.id);
130
+ }
131
+ });
132
+
133
+ function someExpanded(model: TableOfContents.Model): boolean {
134
+ return model.headings.some(h => !(h.collapsed ?? false));
135
+ }
136
+
137
+ app.commands.addCommand(CommandIDs.toggleCollapse, {
138
+ label: () =>
139
+ toc.model && !someExpanded(toc.model)
140
+ ? trans.__('Expand All Headings')
141
+ : trans.__('Collapse All Headings'),
142
+ icon: args =>
143
+ args.toolbar
144
+ ? toc.model && !someExpanded(toc.model)
145
+ ? expandAllIcon
146
+ : collapseAllIcon
147
+ : undefined,
148
+ execute: () => {
149
+ if (toc.model) {
150
+ if (someExpanded(toc.model)) {
151
+ toc.model.toggleCollapse({ collapsed: true });
152
+ } else {
153
+ toc.model.toggleCollapse({ collapsed: false });
154
+ }
155
+ }
156
+ },
157
+ isEnabled: () => toc.model !== null
158
+ });
159
+
160
+ const tracker = new TableOfContentsTracker();
161
+
162
+ if (restorer) {
163
+ // Add the ToC widget to the application restorer:
164
+ restorer.add(toc, '@jupyterlab/toc:plugin');
165
+ }
166
+
167
+ // Attempt to load plugin settings:
168
+ let settings: ISettingRegistry.ISettings | undefined;
169
+ if (settingRegistry) {
170
+ try {
171
+ settings = await settingRegistry.load(registry.id);
172
+ const updateSettings = (plugin: ISettingRegistry.ISettings) => {
173
+ const composite = plugin.composite;
174
+ for (const key of [...Object.keys(configuration)]) {
175
+ const value = composite[key] as any;
176
+ if (value !== undefined) {
177
+ configuration[key] = value;
178
+ }
179
+ }
180
+
181
+ if (labShell) {
182
+ for (const widget of labShell.widgets('main')) {
183
+ const model = tracker.get(widget);
184
+ if (model) {
185
+ model.setConfiguration(configuration);
186
+ }
187
+ }
188
+ } else {
189
+ if (app.shell.currentWidget) {
190
+ const model = tracker.get(app.shell.currentWidget);
191
+ if (model) {
192
+ model.setConfiguration(configuration);
193
+ }
194
+ }
195
+ }
196
+ };
197
+ if (settings) {
198
+ settings.changed.connect(updateSettings);
199
+ updateSettings(settings);
200
+ }
201
+ } catch (error) {
202
+ console.error(
203
+ `Failed to load settings for the Table of Contents extension.\n\n${error}`
204
+ );
205
+ }
206
+ }
207
+
208
+ // Set up the panel toolbar
209
+ const numbering = new CommandToolbarButton({
210
+ commands: app.commands,
211
+ id: CommandIDs.displayNumbering,
212
+ args: {
213
+ toolbar: true
214
+ },
215
+ label: ''
216
+ });
217
+ numbering.addClass('jp-toc-numberingButton');
218
+ toc.toolbar.addItem('display-numbering', numbering);
219
+
220
+ toc.toolbar.addItem('spacer', Toolbar.createSpacerItem());
221
+
222
+ toc.toolbar.addItem(
223
+ 'collapse-all',
224
+ new CommandToolbarButton({
225
+ commands: app.commands,
226
+ id: CommandIDs.toggleCollapse,
227
+ args: {
228
+ toolbar: true
229
+ },
230
+ label: ''
231
+ })
232
+ );
233
+
234
+ const toolbarMenu = new MenuSvg({ commands: app.commands });
235
+ toolbarMenu.addItem({
236
+ command: CommandIDs.displayH1Numbering
237
+ });
238
+ toolbarMenu.addItem({
239
+ command: CommandIDs.displayOutputNumbering
240
+ });
241
+ const menuButton = new ToolbarButton({
242
+ tooltip: trans.__('More actions…'),
243
+ icon: ellipsesIcon,
244
+ actualOnClick: true,
245
+ onClick: () => {
246
+ const bbox = menuButton.node.getBoundingClientRect();
247
+ toolbarMenu.open(bbox.x, bbox.bottom);
248
+ }
249
+ });
250
+ toc.toolbar.addItem('submenu', menuButton);
251
+
252
+ // Add the ToC to the left area:
253
+ app.shell.add(toc, 'left', { rank: 400, type: 'Table of Contents' });
254
+
255
+ // Update the ToC when the active widget changes:
256
+ if (labShell) {
257
+ labShell.currentChanged.connect(onConnect);
258
+ }
259
+
260
+ // Connect to current widget
261
+ void app.restored.then(() => {
262
+ onConnect();
263
+ });
264
+
265
+ return tracker;
266
+
267
+ /**
268
+ * Callback invoked when the active widget changes.
269
+ *
270
+ * @private
271
+ */
272
+ function onConnect() {
273
+ let widget = app.shell.currentWidget;
274
+ if (!widget) {
275
+ return;
276
+ }
277
+ let model = tracker.get(widget);
278
+ if (!model) {
279
+ model = tocRegistry.getModel(widget, configuration) ?? null;
280
+ if (model) {
281
+ tracker.add(widget, model);
282
+ }
283
+
284
+ widget.disposed.connect(() => {
285
+ model?.dispose();
286
+ });
287
+ }
288
+
289
+ if (toc.model) {
290
+ toc.model.headingsChanged.disconnect(onCollapseChange);
291
+ toc.model.collapseChanged.disconnect(onCollapseChange);
292
+ }
293
+
294
+ toc.model = model;
295
+ if (toc.model) {
296
+ toc.model.headingsChanged.connect(onCollapseChange);
297
+ toc.model.collapseChanged.connect(onCollapseChange);
298
+ }
299
+ setToolbarButtonsState();
300
+ }
301
+
302
+ function setToolbarButtonsState() {
303
+ app.commands.notifyCommandChanged(CommandIDs.displayNumbering);
304
+ app.commands.notifyCommandChanged(CommandIDs.toggleCollapse);
305
+ }
306
+
307
+ function onCollapseChange() {
308
+ app.commands.notifyCommandChanged(CommandIDs.toggleCollapse);
309
+ }
310
+ }
311
+
312
+ /**
313
+ * Table of contents registry plugin.
314
+ */
315
+ const registry: JupyterFrontEndPlugin<ITableOfContentsRegistry> = {
316
+ id: '@jupyterlab/toc-extension:registry',
317
+ autoStart: true,
318
+ provides: ITableOfContentsRegistry,
319
+ activate: (): ITableOfContentsRegistry => {
320
+ // Create the ToC registry
321
+ return new TableOfContentsRegistry();
322
+ }
323
+ };
324
+
325
+ /**
326
+ * Table of contents tracker plugin.
327
+ */
328
+ const tracker: JupyterFrontEndPlugin<ITableOfContentsTracker> = {
329
+ id: '@jupyterlab/toc-extension:tracker',
330
+ autoStart: true,
331
+ provides: ITableOfContentsTracker,
332
+ requires: [ITableOfContentsRegistry],
333
+ optional: [ITranslator, ILayoutRestorer, ILabShell, ISettingRegistry],
334
+ activate: activateTOC
335
+ };
336
+
337
+ /**
338
+ * Exports.
339
+ */
340
+ export default [registry, tracker];