forked from jupyterlab/jupyterlab
/
index.ts
142 lines (126 loc) · 3.84 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
// Copyright (c) Jupyter Development Team.
// Distributed under the terms of the Modified BSD License.
import {
ILabShell,
ILayoutRestorer,
JupyterFrontEnd,
JupyterFrontEndPlugin
} from '@jupyterlab/application';
import { Dialog, showDialog, ICommandPalette } from '@jupyterlab/apputils';
import { ISettingRegistry } from '@jupyterlab/coreutils';
import { IMainMenu } from '@jupyterlab/mainmenu';
import { ExtensionView } from '@jupyterlab/extensionmanager';
/**
* IDs of the commands added by this extension.
*/
namespace CommandIDs {
export const toggle = 'extensionmanager:toggle';
}
/**
* The extension manager plugin.
*/
const plugin: JupyterFrontEndPlugin<void> = {
id: '@jupyterlab/extensionmanager-extension:plugin',
autoStart: true,
requires: [ISettingRegistry],
optional: [ILabShell, ILayoutRestorer, IMainMenu, ICommandPalette],
activate: async (
app: JupyterFrontEnd,
registry: ISettingRegistry,
labShell: ILabShell | null,
restorer: ILayoutRestorer | null,
mainMenu: IMainMenu | null,
palette: ICommandPalette | null
) => {
const settings = await registry.load(plugin.id);
let enabled = settings.composite['enabled'] === true;
const { commands, serviceManager, shell } = app;
let view: ExtensionView | undefined;
const createView = () => {
const v = new ExtensionView(serviceManager);
v.id = 'extensionmanager.main-view';
v.title.iconClass = 'jp-ExtensionIcon jp-SideBar-tabIcon';
v.title.caption = 'Extension Manager';
if (restorer) {
restorer.add(v, v.id);
}
return v;
};
if (enabled) {
view = createView();
shell.add(view, 'left', { rank: 1000 });
}
// If the extension is enabled or disabled,
// add or remove it from the left area.
void app.restored.then(() => {
settings.changed.connect(async () => {
enabled = settings.composite['enabled'] === true;
if (enabled && (!view || (view && !view.isAttached))) {
const accepted = await Private.showWarning();
if (!accepted) {
void settings.set('enabled', false);
return;
}
view = view || createView();
shell.add(view, 'left');
} else if (!enabled && view && view.isAttached) {
view.close();
}
});
});
commands.addCommand(CommandIDs.toggle, {
label: 'Enable Extension Manager (experimental)',
execute: () => {
if (registry) {
void registry.set(plugin.id, 'enabled', !enabled);
}
},
isToggled: () => enabled,
isEnabled: () => serviceManager.builder.isAvailable
});
const category = 'Extension Manager';
const command = CommandIDs.toggle;
if (palette) {
palette.addItem({ command, category });
}
if (mainMenu) {
mainMenu.settingsMenu.addGroup([{ command }], 100);
}
}
};
/**
* Export the plugin as the default.
*/
export default plugin;
/**
* A namespace for module-private functions.
*/
namespace Private {
/**
* Show a warning dialog about extension security.
*
* @returns whether the user accepted the dialog.
*/
export async function showWarning(): Promise<boolean> {
return showDialog({
title: 'Enable Extension Manager?',
body:
"Thanks for trying out JupyterLab's extension manager. " +
'The JupyterLab development team is excited to have a robust ' +
'third-party extension community. ' +
'However, we cannot vouch for every extension, ' +
'and some may introduce security risks. ' +
'Do you want to continue?',
buttons: [
Dialog.cancelButton({ label: 'DISABLE' }),
Dialog.warnButton({ label: 'ENABLE' })
]
}).then(result => {
if (result.button.accept) {
return true;
} else {
return false;
}
});
}
}