This repository was archived by the owner on Mar 6, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathPluginLoader.js
More file actions
94 lines (83 loc) · 2.44 KB
/
Copy pathPluginLoader.js
File metadata and controls
94 lines (83 loc) · 2.44 KB
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
import PluginMeta from './models/PluginMeta';
/**
* Return the global Require.js function.
*/
function getRequireJs() {
return window.requirejs;
}
/**
* Parse a plugin URL into an object containing its parts. Old plugins normally
* used the require.js optimizer for bundling, and exposed multiple require.js
* modules. New plugins tend to be built using Webpack and expose a single
* anonymous module, which can be `require`d by its URL alone.
* Because old plugins exposed multiple named require.js modules, they cannot
* be loaded by their URL alone, but we also need to know the entry point module
* name. A plugin URL of the form `<url>;<entry-point>` was used to accomplish
* that.
*/
function parseLegacyPluginUrl(name) {
const parts = name.split(';');
const o = {};
o.url = parts[0];
if (parts[1]) {
o.name = parts[1];
}
// force https
o.url = o.url.replace(/^http:/, 'https:');
return o;
}
export default class PluginLoader {
constructor() {
this.require = getRequireJs();
}
/**
* Add a module name alias to the plugin URL. This way, when we
* require([ module name ]), the plugin URL will be loaded instead. Then, the
* plugin URL will define() the module name anyway, and requirejs will figure
* everything out.
*/
injectModuleAlias(o) {
this.require({
paths: {
// Chopping off the .js extension because require.js adds it
// since we're actually requiring a module name and not a path.
[o.name]: o.url.replace(/\.js$/, ''),
},
});
}
/**
* Load a plugin.
*/
load(url) {
const o = parseLegacyPluginUrl(url);
if (o.name) {
this.injectModuleAlias(o);
}
const pluginId = o.name || o.url;
const onLoad = resolve => (module) => {
const PluginClass = module.default || module;
const instance = new PluginClass(pluginId, window.extp);
const meta = new PluginMeta({
id: pluginId,
fullUrl: o.url,
name: instance.name,
description: instance.description,
instance,
class: PluginClass,
});
resolve(meta);
};
return new Promise((resolve, reject) => {
this.require([pluginId], onLoad(resolve), reject);
});
}
/**
* Unload a plugin.
*/
unload(url) {
// Attempt to remove the plugin from the require.js registry. This doesn't
// work for plugins using the legacy URL format.
this.require.undef(url);
return Promise.resolve();
}
}