/
index.ts
158 lines (146 loc) · 4.59 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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
// Copyright (c) Jupyter Development Team.
// Distributed under the terms of the Modified BSD License.
/**
* @packageDocumentation
* @module extensionmanager-extension
*/
import {
ILabShell,
ILayoutRestorer,
JupyterFrontEnd,
JupyterFrontEndPlugin
} from '@jupyterlab/application';
import { Dialog, ICommandPalette, showDialog } from '@jupyterlab/apputils';
import { ExtensionView } from '@jupyterlab/extensionmanager';
import { ISettingRegistry } from '@jupyterlab/settingregistry';
import { ITranslator, TranslationBundle } from '@jupyterlab/translation';
import { extensionIcon } from '@jupyterlab/ui-components';
const PLUGIN_ID = '@jupyterlab/extensionmanager-extension:plugin';
/**
* IDs of the commands added by this extension.
*/
namespace CommandIDs {
export const toggle = 'extensionmanager:toggle';
}
/**
* The extension manager plugin.
*/
const plugin: JupyterFrontEndPlugin<void> = {
id: PLUGIN_ID,
autoStart: true,
requires: [ISettingRegistry, ITranslator],
optional: [ILabShell, ILayoutRestorer, ICommandPalette],
activate: async (
app: JupyterFrontEnd,
registry: ISettingRegistry,
translator: ITranslator,
labShell: ILabShell | null,
restorer: ILayoutRestorer | null,
palette: ICommandPalette | null
) => {
const trans = translator.load('jupyterlab');
const settings = await registry.load(plugin.id);
let enabled = settings.composite['enabled'] === true;
const { commands, serviceManager } = app;
let view: ExtensionView | undefined;
const createView = () => {
const v = new ExtensionView(app, serviceManager, settings, translator);
v.id = 'extensionmanager.main-view';
v.title.icon = extensionIcon;
v.title.caption = trans.__('Extension Manager');
if (restorer) {
restorer.add(v, v.id);
}
return v;
};
if (enabled && labShell) {
view = createView();
view.node.setAttribute('role', 'region');
view.node.setAttribute(
'aria-label',
trans.__('Extension Manager section')
);
labShell.add(view, 'left', { rank: 1000 });
}
// If the extension is enabled or disabled,
// add or remove it from the left area.
Promise.all([app.restored, registry.load(PLUGIN_ID)])
.then(([, settings]) => {
settings.changed.connect(async () => {
enabled = settings.composite['enabled'] === true;
if (enabled && !view?.isAttached) {
const accepted = await Private.showWarning(trans);
if (!accepted) {
void settings.set('enabled', false);
return;
}
view = view || createView();
view.node.setAttribute('role', 'region');
view.node.setAttribute(
'aria-label',
trans.__('Extension Manager section')
);
if (labShell) {
labShell.add(view, 'left', { rank: 1000 });
}
} else if (!enabled && view?.isAttached) {
app.commands.notifyCommandChanged(CommandIDs.toggle);
view.close();
}
});
})
.catch(reason => {
console.error(
`Something went wrong when reading the settings.\n${reason}`
);
});
commands.addCommand(CommandIDs.toggle, {
label: trans.__('Enable Extension Manager'),
execute: () => {
if (registry) {
void registry.set(plugin.id, 'enabled', !enabled);
}
},
isToggled: () => enabled,
isEnabled: () => serviceManager.builder.isAvailable
});
const category = trans.__('Extension Manager');
const command = CommandIDs.toggle;
if (palette) {
palette.addItem({ command, category });
}
}
};
/**
* 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(
trans: TranslationBundle
): Promise<boolean> {
return showDialog({
title: trans.__('Enable Extension Manager?'),
body: trans.__(`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: trans.__('Disable') }),
Dialog.warnButton({ label: trans.__('Enable') })
]
}).then(result => {
return result.button.accept;
});
}
}