1
0
Fork 0
mirror of https://github.com/jellyfin/jellyfin-web synced 2025-03-30 19:56:21 +00:00

Merge pull request #1716 from MrTimscampi/pluginmanager-es6

Migrate PluginManager and PackageManager to ES6
This commit is contained in:
Joshua M. Boniface 2020-08-16 12:17:22 -04:00 committed by GitHub
commit e4a922ad60
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 256 additions and 240 deletions

View file

@ -40,13 +40,13 @@ module.exports = {
'no-multi-spaces': ['error'], 'no-multi-spaces': ['error'],
'no-multiple-empty-lines': ['error', { 'max': 1 }], 'no-multiple-empty-lines': ['error', { 'max': 1 }],
'no-trailing-spaces': ['error'], 'no-trailing-spaces': ['error'],
'no-unused-expressions': ['error', { 'allowShortCircuit': true, 'allowTernary': true, 'allowTaggedTemplates': true }], '@babel/no-unused-expressions': ['error', { 'allowShortCircuit': true, 'allowTernary': true, 'allowTaggedTemplates': true }],
'no-unused-vars': ['error', { 'vars': 'all', 'args': 'none', 'ignoreRestSiblings': true }], //'no-unused-vars': ['error', { 'vars': 'all', 'args': 'none', 'ignoreRestSiblings': true }],
'one-var': ['error', 'never'], 'one-var': ['error', 'never'],
'padded-blocks': ['error', 'never'], 'padded-blocks': ['error', 'never'],
//'prefer-const': ['error', {'destructuring': 'all'}], //'prefer-const': ['error', {'destructuring': 'all'}],
'quotes': ['error', 'single', { 'avoidEscape': true, 'allowTemplateLiterals': false }], 'quotes': ['error', 'single', { 'avoidEscape': true, 'allowTemplateLiterals': false }],
'semi': ['error'], '@babel/semi': ['error'],
'space-before-blocks': ['error'], 'space-before-blocks': ['error'],
'space-infix-ops': 'error', 'space-infix-ops': 'error',
'yoda': 'error' 'yoda': 'error'
@ -106,6 +106,7 @@ module.exports = {
// TODO: Fix warnings and remove these rules // TODO: Fix warnings and remove these rules
'no-redeclare': ['off'], 'no-redeclare': ['off'],
'no-useless-escape': ['off'], 'no-useless-escape': ['off'],
'no-unused-vars': ['off'],
// TODO: Remove after ES6 migration is complete // TODO: Remove after ES6 migration is complete
'import/no-unresolved': ['off'] 'import/no-unresolved': ['off']
}, },

View file

@ -145,6 +145,7 @@
"src/components/multiSelect/multiSelect.js", "src/components/multiSelect/multiSelect.js",
"src/components/notifications/notifications.js", "src/components/notifications/notifications.js",
"src/components/nowPlayingBar/nowPlayingBar.js", "src/components/nowPlayingBar/nowPlayingBar.js",
"src/components/packageManager.js",
"src/components/playback/brightnessosd.js", "src/components/playback/brightnessosd.js",
"src/components/playback/mediasession.js", "src/components/playback/mediasession.js",
"src/components/playback/nowplayinghelper.js", "src/components/playback/nowplayinghelper.js",
@ -160,6 +161,7 @@
"src/components/playerstats/playerstats.js", "src/components/playerstats/playerstats.js",
"src/components/playlisteditor/playlisteditor.js", "src/components/playlisteditor/playlisteditor.js",
"src/components/playmenu.js", "src/components/playmenu.js",
"src/components/pluginManager.js",
"src/components/prompt/prompt.js", "src/components/prompt/prompt.js",
"src/components/recordingcreator/recordingbutton.js", "src/components/recordingcreator/recordingbutton.js",
"src/components/recordingcreator/recordingcreator.js", "src/components/recordingcreator/recordingcreator.js",

View file

@ -1117,7 +1117,7 @@ import 'programStyles';
function importRefreshIndicator() { function importRefreshIndicator() {
if (!refreshIndicatorLoaded) { if (!refreshIndicatorLoaded) {
refreshIndicatorLoaded = true; refreshIndicatorLoaded = true;
/* eslint-disable-next-line no-unused-expressions */ /* eslint-disable-next-line @babel/no-unused-expressions */
import('emby-itemrefreshindicator'); import('emby-itemrefreshindicator');
} }
} }
@ -1449,7 +1449,7 @@ import 'programStyles';
const userData = item.UserData || {}; const userData = item.UserData || {};
if (itemHelper.canMarkPlayed(item)) { if (itemHelper.canMarkPlayed(item)) {
/* eslint-disable-next-line no-unused-expressions */ /* eslint-disable-next-line @babel/no-unused-expressions */
import('emby-playstatebutton'); import('emby-playstatebutton');
html += '<button is="emby-playstatebutton" type="button" data-action="none" class="' + btnCssClass + '" data-id="' + item.Id + '" data-serverid="' + item.ServerId + '" data-itemtype="' + item.Type + '" data-played="' + (userData.Played) + '"><span class="material-icons cardOverlayButtonIcon cardOverlayButtonIcon-hover check"></span></button>'; html += '<button is="emby-playstatebutton" type="button" data-action="none" class="' + btnCssClass + '" data-id="' + item.Id + '" data-serverid="' + item.ServerId + '" data-itemtype="' + item.Type + '" data-played="' + (userData.Played) + '"><span class="material-icons cardOverlayButtonIcon cardOverlayButtonIcon-hover check"></span></button>';
} }
@ -1457,7 +1457,7 @@ import 'programStyles';
if (itemHelper.canRate(item)) { if (itemHelper.canRate(item)) {
const likes = userData.Likes == null ? '' : userData.Likes; const likes = userData.Likes == null ? '' : userData.Likes;
/* eslint-disable-next-line no-unused-expressions */ /* eslint-disable-next-line @babel/no-unused-expressions */
import('emby-ratingbutton'); import('emby-ratingbutton');
html += '<button is="emby-ratingbutton" type="button" data-action="none" class="' + btnCssClass + '" data-id="' + item.Id + '" data-serverid="' + item.ServerId + '" data-itemtype="' + item.Type + '" data-likes="' + likes + '" data-isfavorite="' + (userData.IsFavorite) + '"><span class="material-icons cardOverlayButtonIcon cardOverlayButtonIcon-hover favorite"></span></button>'; html += '<button is="emby-ratingbutton" type="button" data-action="none" class="' + btnCssClass + '" data-id="' + item.Id + '" data-serverid="' + item.ServerId + '" data-itemtype="' + item.Type + '" data-likes="' + likes + '" data-isfavorite="' + (userData.IsFavorite) + '"><span class="material-icons cardOverlayButtonIcon cardOverlayButtonIcon-hover favorite"></span></button>';
} }

View file

@ -1,134 +1,140 @@
define(['appSettings', 'pluginManager'], function (appSettings, pluginManager) { import appSettings from 'appSettings';
'use strict'; import pluginManager from 'pluginManager';
/* eslint-disable indent */
var settingsKey = 'installedpackages1'; class PackageManager {
#packagesList = [];
#settingsKey = 'installedpackages1';
function addPackage(packageManager, pkg) { init() {
packageManager.packagesList = packageManager.packagesList.filter(function (p) { console.groupCollapsed('loading packages');
return p.name !== pkg.name; var manifestUrls = JSON.parse(appSettings.get(this.#settingsKey) || '[]');
});
packageManager.packagesList.push(pkg); return Promise.all(manifestUrls.map((url) => {
} return this.loadPackage(url);
}))
.then(() => {
console.debug('finished loading packages');
return Promise.resolve();
})
.catch(() => {
return Promise.resolve();
}).finally(() => {
console.groupEnd('loading packages');
});
}
function removeUrl(url) { get packages() {
var manifestUrls = JSON.parse(appSettings.get(settingsKey) || '[]'); return this.#packagesList.slice(0);
}
manifestUrls = manifestUrls.filter(function (i) { install(url) {
return i !== url; return this.loadPackage(url, true).then((pkg) => {
}); var manifestUrls = JSON.parse(appSettings.get(this.#settingsKey) || '[]');
appSettings.set(settingsKey, JSON.stringify(manifestUrls)); if (!manifestUrls.includes(url)) {
} manifestUrls.push(url);
appSettings.set(this.#settingsKey, JSON.stringify(manifestUrls));
function loadPackage(packageManager, url, throwError) {
return new Promise(function (resolve, reject) {
var xhr = new XMLHttpRequest();
var originalUrl = url;
url += url.indexOf('?') === -1 ? '?' : '&';
url += 't=' + new Date().getTime();
xhr.open('GET', url, true);
var onError = function () {
if (throwError === true) {
reject();
} else {
removeUrl(originalUrl);
resolve();
} }
};
xhr.onload = function (e) { return pkg;
if (this.status < 400) { });
var pkg = JSON.parse(this.response); }
pkg.url = originalUrl;
addPackage(packageManager, pkg); uninstall(name) {
var pkg = this.#packagesList.filter((p) => {
return p.name === name;
})[0];
var plugins = pkg.plugins || []; if (pkg) {
if (pkg.plugin) { this.#packagesList = this.#packagesList.filter((p) => {
plugins.push(pkg.plugin); return p.name !== name;
} });
var promises = plugins.map(function (pluginUrl) {
return pluginManager.loadPlugin(packageManager.mapPath(pkg, pluginUrl));
});
Promise.all(promises).then(resolve, resolve);
} else {
onError();
}
};
xhr.onerror = onError; this.removeUrl(pkg.url);
xhr.send();
});
}
function PackageManager() {
this.packagesList = [];
}
PackageManager.prototype.init = function () {
var manifestUrls = JSON.parse(appSettings.get(settingsKey) || '[]');
var instance = this;
return Promise.all(manifestUrls.map(function (u) {
return loadPackage(instance, u);
})).then(function () {
return Promise.resolve();
}, function () {
return Promise.resolve();
});
};
PackageManager.prototype.packages = function () {
return this.packagesList.slice(0);
};
PackageManager.prototype.install = function (url) {
return loadPackage(this, url, true).then(function (pkg) {
var manifestUrls = JSON.parse(appSettings.get(settingsKey) || '[]');
if (manifestUrls.indexOf(url) === -1) {
manifestUrls.push(url);
appSettings.set(settingsKey, JSON.stringify(manifestUrls));
} }
return pkg; return Promise.resolve();
}); }
};
PackageManager.prototype.uninstall = function (name) { mapPath(pkg, pluginUrl) {
var pkg = this.packagesList.filter(function (p) { var urlLower = pluginUrl.toLowerCase();
return p.name === name; if (urlLower.startsWith('http:') || urlLower.startsWith('https:') || urlLower.startsWith('file:')) {
})[0]; return pluginUrl;
}
if (pkg) { var packageUrl = pkg.url;
this.packagesList = this.packagesList.filter(function (p) { packageUrl = packageUrl.substring(0, packageUrl.lastIndexOf('/'));
return p.name !== name;
packageUrl += '/';
packageUrl += pluginUrl;
return packageUrl;
}
addPackage(pkg) {
this.#packagesList = this.#packagesList.filter((p) => {
return p.name !== pkg.name;
}); });
removeUrl(pkg.url); this.#packagesList.push(pkg);
} }
return Promise.resolve(); removeUrl(url) {
}; var manifestUrls = JSON.parse(appSettings.get(this.#settingsKey) || '[]');
PackageManager.prototype.mapPath = function (pkg, pluginUrl) { manifestUrls = manifestUrls.filter((i) => {
var urlLower = pluginUrl.toLowerCase(); return i !== url;
if (urlLower.indexOf('http:') === 0 || urlLower.indexOf('https:') === 0 || urlLower.indexOf('file:') === 0) { });
return pluginUrl;
appSettings.set(this.#settingsKey, JSON.stringify(manifestUrls));
} }
var packageUrl = pkg.url; loadPackage(url, throwError = false) {
packageUrl = packageUrl.substring(0, packageUrl.lastIndexOf('/')); return new Promise((resolve, reject) => {
var xhr = new XMLHttpRequest();
var originalUrl = url;
url += url.indexOf('?') === -1 ? '?' : '&';
url += 't=' + new Date().getTime();
packageUrl += '/'; xhr.open('GET', url, true);
packageUrl += pluginUrl;
return packageUrl; var onError = () => {
}; if (throwError === true) {
reject();
} else {
this.removeUrl(originalUrl);
resolve();
}
};
return new PackageManager(); xhr.onload = () => {
}); if (this.status < 400) {
var pkg = JSON.parse(this.response);
pkg.url = originalUrl;
this.addPackage(pkg);
var plugins = pkg.plugins || [];
if (pkg.plugin) {
plugins.push(pkg.plugin);
}
var promises = plugins.map((pluginUrl) => {
return pluginManager.loadPlugin(this.mapPath(pkg, pluginUrl));
});
Promise.all(promises).then(resolve, resolve);
} else {
onError();
}
};
xhr.onerror = onError;
xhr.send();
});
}
}
/* eslint-enable indent */
export default new PackageManager();

View file

@ -1,37 +1,38 @@
define(['events', 'globalize'], function (events, globalize) { import events from 'events';
'use strict'; import globalize from 'globalize';
/* eslint-disable indent */
// TODO: replace with each plugin version // TODO: replace with each plugin version
var cacheParam = new Date().getTime(); var cacheParam = new Date().getTime();
function loadStrings(plugin) { class PluginManager {
var strings = plugin.getTranslations ? plugin.getTranslations() : []; pluginsList = [];
return globalize.loadStrings({
name: plugin.id || plugin.packageName,
strings: strings
});
}
function definePluginRoute(pluginManager, route, plugin) { get plugins() {
route.contentPath = pluginManager.mapPath(plugin, route.path); return this.pluginsList;
route.path = pluginManager.mapRoute(plugin, route); }
Emby.App.defineRoute(route, plugin.id); #loadStrings(plugin) {
} var strings = plugin.getTranslations ? plugin.getTranslations() : [];
return globalize.loadStrings({
name: plugin.id || plugin.packageName,
strings: strings
});
}
function PluginManager() { #definePluginRoute(route, plugin) {
this.pluginsList = []; route.contentPath = this.mapPath(plugin, route.path);
} route.path = this.#mapRoute(plugin, route);
PluginManager.prototype.loadPlugin = function(pluginSpec) { Emby.App.defineRoute(route, plugin.id);
var instance = this; }
function registerPlugin(plugin) { #registerPlugin(plugin) {
instance.register(plugin); this.#register(plugin);
if (plugin.getRoutes) { if (plugin.getRoutes) {
plugin.getRoutes().forEach(function (route) { plugin.getRoutes().forEach((route) => {
definePluginRoute(instance, route, plugin); this.#definePluginRoute(route, plugin);
}); });
} }
@ -40,7 +41,7 @@ define(['events', 'globalize'], function (events, globalize) {
return Promise.resolve(plugin); return Promise.resolve(plugin);
} else { } else {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
loadStrings(plugin) this.#loadStrings(plugin)
.then(function () { .then(function () {
resolve(plugin); resolve(plugin);
}) })
@ -49,103 +50,102 @@ define(['events', 'globalize'], function (events, globalize) {
} }
} }
if (typeof pluginSpec === 'string') { loadPlugin(pluginSpec) {
console.debug('Loading plugin (via deprecated requirejs method): ' + pluginSpec); if (typeof pluginSpec === 'string') {
console.debug('Loading plugin (via deprecated requirejs method): ' + pluginSpec);
return new Promise(function (resolve, reject) { return new Promise((resolve, reject) => {
require([pluginSpec], (pluginFactory) => { require([pluginSpec], (pluginFactory) => {
var plugin = pluginFactory.default ? new pluginFactory.default() : new pluginFactory(); var plugin = pluginFactory.default ? new pluginFactory.default() : new pluginFactory();
// See if it's already installed // See if it's already installed
var existing = instance.pluginsList.filter(function (p) { var existing = this.pluginsList.filter(function (p) {
return p.id === plugin.id; return p.id === plugin.id;
})[0]; })[0];
if (existing) { if (existing) {
resolve(pluginSpec); resolve(pluginSpec);
} }
plugin.installUrl = pluginSpec; plugin.installUrl = pluginSpec;
var separatorIndex = Math.max(pluginSpec.lastIndexOf('/'), pluginSpec.lastIndexOf('\\')); var separatorIndex = Math.max(pluginSpec.lastIndexOf('/'), pluginSpec.lastIndexOf('\\'));
plugin.baseUrl = pluginSpec.substring(0, separatorIndex); plugin.baseUrl = pluginSpec.substring(0, separatorIndex);
var paths = {}; var paths = {};
paths[plugin.id] = plugin.baseUrl; paths[plugin.id] = plugin.baseUrl;
requirejs.config({ requirejs.config({
waitSeconds: 0, waitSeconds: 0,
paths: paths paths: paths
});
this.#registerPlugin(plugin).then(resolve).catch(reject);
}); });
registerPlugin(plugin).then(resolve).catch(reject);
}); });
} else if (pluginSpec.then) {
return pluginSpec.then(pluginBuilder => {
return pluginBuilder();
}).then((plugin) => {
console.debug(`Plugin loaded: ${plugin.id}`);
return this.#registerPlugin(plugin);
});
} else {
const err = new TypeError('Plugins have to be a Promise that resolves to a plugin builder function or a RequireJS url (deprecated)');
console.error(err);
return Promise.reject(err);
}
}
// In lieu of automatic discovery, plugins will register dynamic objects
// Each object will have the following properties:
// name
// type (skin, screensaver, etc)
#register(obj) {
this.pluginsList.push(obj);
events.trigger(this, 'registered', [obj]);
}
ofType(type) {
return this.pluginsList.filter((o) => {
return o.type === type;
}); });
} else if (pluginSpec.then) {
return pluginSpec.then(pluginBuilder => {
return pluginBuilder();
}).then(plugin => {
console.debug(`Plugin loaded: ${plugin.id}`);
return registerPlugin(plugin);
});
} else {
const err = new Error('Plugins have to be a Promise that resolves to a plugin builder function or a requirejs urls (deprecated)');
console.error(err);
return Promise.reject(err);
}
};
// In lieu of automatic discovery, plugins will register dynamic objects
// Each object will have the following properties:
// name
// type (skin, screensaver, etc)
PluginManager.prototype.register = function (obj) {
this.pluginsList.push(obj);
events.trigger(this, 'registered', [obj]);
};
PluginManager.prototype.ofType = function (type) {
return this.pluginsList.filter(function (o) {
return o.type === type;
});
};
PluginManager.prototype.plugins = function () {
return this.pluginsList;
};
PluginManager.prototype.mapRoute = function (plugin, route) {
if (typeof plugin === 'string') {
plugin = this.pluginsList.filter(function (p) {
return (p.id || p.packageName) === plugin;
})[0];
} }
route = route.path || route; #mapRoute(plugin, route) {
if (typeof plugin === 'string') {
plugin = this.pluginsList.filter((p) => {
return (p.id || p.packageName) === plugin;
})[0];
}
if (route.toLowerCase().indexOf('http') === 0) { route = route.path || route;
return route;
if (route.toLowerCase().startsWith('http')) {
return route;
}
return '/plugins/' + plugin.id + '/' + route;
} }
return '/plugins/' + plugin.id + '/' + route; mapPath(plugin, path, addCacheParam) {
}; if (typeof plugin === 'string') {
plugin = this.pluginsList.filter((p) => {
return (p.id || p.packageName) === plugin;
})[0];
}
PluginManager.prototype.mapPath = function (plugin, path, addCacheParam) { var url = plugin.baseUrl + '/' + path;
if (typeof plugin === 'string') {
plugin = this.pluginsList.filter(function (p) { if (addCacheParam) {
return (p.id || p.packageName) === plugin; url += url.includes('?') ? '&' : '?';
})[0]; url += 'v=' + cacheParam;
}
return url;
} }
}
var url = plugin.baseUrl + '/' + path; /* eslint-enable indent */
if (addCacheParam) { export default new PluginManager();
url += url.indexOf('?') === -1 ? '?' : '&';
url += 'v=' + cacheParam;
}
return url;
};
return new PluginManager();
});

View file

@ -150,7 +150,7 @@ function tryRemoveElement(elem) {
/** /**
* @type {string} * @type {string}
*/ */
name name;
/** /**
* @type {string} * @type {string}
*/ */
@ -730,7 +730,7 @@ function tryRemoveElement(elem) {
const elem = e.target; const elem = e.target;
this.destroyCustomTrack(elem); this.destroyCustomTrack(elem);
onEndedInternal(this, elem, this.onError); onEndedInternal(this, elem, this.onError);
} };
/** /**
* @private * @private
@ -760,7 +760,7 @@ function tryRemoveElement(elem) {
} }
events.trigger(this, 'timeupdate'); events.trigger(this, 'timeupdate');
} };
/** /**
* @private * @private
@ -773,7 +773,7 @@ function tryRemoveElement(elem) {
const elem = e.target; const elem = e.target;
saveVolume(elem.volume); saveVolume(elem.volume);
events.trigger(this, 'volumechange'); events.trigger(this, 'volumechange');
} };
/** /**
* @private * @private
@ -785,7 +785,7 @@ function tryRemoveElement(elem) {
this.onStartedAndNavigatedToOsd(); this.onStartedAndNavigatedToOsd();
} }
} };
/** /**
* @private * @private
@ -832,14 +832,14 @@ function tryRemoveElement(elem) {
} }
} }
events.trigger(this, 'playing'); events.trigger(this, 'playing');
} };
/** /**
* @private * @private
*/ */
onPlay = () => { onPlay = () => {
events.trigger(this, 'unpause'); events.trigger(this, 'unpause');
} };
/** /**
* @private * @private
@ -865,21 +865,21 @@ function tryRemoveElement(elem) {
*/ */
onClick = () => { onClick = () => {
events.trigger(this, 'click'); events.trigger(this, 'click');
} };
/** /**
* @private * @private
*/ */
onDblClick = () => { onDblClick = () => {
events.trigger(this, 'dblclick'); events.trigger(this, 'dblclick');
} };
/** /**
* @private * @private
*/ */
onPause = () => { onPause = () => {
events.trigger(this, 'pause'); events.trigger(this, 'pause');
} };
onWaiting() { onWaiting() {
events.trigger(this, 'waiting'); events.trigger(this, 'waiting');
@ -929,7 +929,7 @@ function tryRemoveElement(elem) {
} }
onErrorInternal(this, type); onErrorInternal(this, type);
} };
/** /**
* @private * @private

View file

@ -302,7 +302,7 @@ import 'material-icons';
$(document).on('itemsaved', '.metadataEditorPage', function (e, item) { $(document).on('itemsaved', '.metadataEditorPage', function (e, item) {
updateEditorNode(this, item); updateEditorNode(this, item);
}).on('pagebeforeshow', '.metadataEditorPage', function () { }).on('pagebeforeshow', '.metadataEditorPage', function () {
/* eslint-disable-next-line no-unused-expressions */ /* eslint-disable-next-line @babel/no-unused-expressions */
import('css!assets/css/metadataeditor.css'); import('css!assets/css/metadataeditor.css');
}).on('pagebeforeshow', '.metadataEditorPage', function () { }).on('pagebeforeshow', '.metadataEditorPage', function () {
var page = this; var page = this;

View file

@ -155,7 +155,7 @@ export function enable() {
function attachGamepadScript(e) { function attachGamepadScript(e) {
console.log('Gamepad connected! Attaching gamepadtokey.js script'); console.log('Gamepad connected! Attaching gamepadtokey.js script');
window.removeEventListener('gamepadconnected', attachGamepadScript); window.removeEventListener('gamepadconnected', attachGamepadScript);
/* eslint-disable-next-line no-unused-expressions */ /* eslint-disable-next-line @babel/no-unused-expressions */
import('scripts/gamepadtokey'); import('scripts/gamepadtokey');
} }

View file

@ -479,7 +479,7 @@ function initClient() {
} }
function loadPlugins(appHost, browser, shell) { function loadPlugins(appHost, browser, shell) {
console.debug('loading installed plugins'); console.groupCollapsed('loading installed plugins');
return new Promise(function (resolve, reject) { return new Promise(function (resolve, reject) {
require(['webSettings'], function (webSettings) { require(['webSettings'], function (webSettings) {
webSettings.getPlugins().then(function (list) { webSettings.getPlugins().then(function (list) {
@ -497,11 +497,18 @@ function initClient() {
list = list.concat(window.NativeShell.getPlugins()); list = list.concat(window.NativeShell.getPlugins());
} }
Promise.all(list.map(loadPlugin)).then(function () { Promise.all(list.map(loadPlugin))
require(['packageManager'], function (packageManager) { .then(function () {
packageManager.init().then(resolve, reject); console.debug('finished loading plugins');
}); })
}, reject); .catch(() => reject)
.finally(() => {
console.groupEnd('loading installed plugins');
require(['packageManager'], function (packageManager) {
packageManager.default.init().then(resolve, reject);
});
})
;
}); });
}); });
}); });
@ -510,7 +517,7 @@ function initClient() {
function loadPlugin(url) { function loadPlugin(url) {
return new Promise(function (resolve, reject) { return new Promise(function (resolve, reject) {
require(['pluginManager'], function (pluginManager) { require(['pluginManager'], function (pluginManager) {
pluginManager.loadPlugin(url).then(resolve, reject); pluginManager.default.loadPlugin(url).then(resolve, reject);
}); });
}); });
} }