diff --git a/frontend-js/package-lock.json b/frontend-js/package-lock.json index f036ef8b1e0501e11e38d605b97ca4fde8a375e2..90394fa15961b126b3fa198f2166b6e850079e06 100644 --- a/frontend-js/package-lock.json +++ b/frontend-js/package-lock.json @@ -1611,6 +1611,11 @@ "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" }, + "is-url": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.2.tgz", + "integrity": "sha1-SYkFpZO/R8wtnn9zg3K792lsfyY=" + }, "isarray": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", diff --git a/frontend-js/package.json b/frontend-js/package.json index 9dcf2e6e8c98b4f08810c1ce11226536ac082c9b..d2df88611ab312dea8ff6adf412c021032c5a876 100644 --- a/frontend-js/package.json +++ b/frontend-js/package.json @@ -41,6 +41,7 @@ "dual-listbox": "1.0.7", "file-saver": "^1.3.3", "http-status-codes": "^1.3.0", + "is-url": "^1.2.2", "js-cookie": "^2.1.3", "jstree": "^3.3.4", "jszip": "^3.1.4", diff --git a/frontend-js/src/main/js/plugin/PluginManager.js b/frontend-js/src/main/js/plugin/PluginManager.js index 1b16af8995ba8164ff0e6ae5c3f388d5d9760906..d24d4095e74cdf755a92c54b212116113fb7869a 100644 --- a/frontend-js/src/main/js/plugin/PluginManager.js +++ b/frontend-js/src/main/js/plugin/PluginManager.js @@ -1,177 +1,185 @@ -"use strict"; - -var ObjectWithListeners = require('../ObjectWithListeners'); -var Plugin = require('./Plugin'); -var GuiUtils = require('../gui/leftPanel/GuiUtils'); -var GuiConnector = require('../GuiConnector'); - -var Promise = require("bluebird"); - -// noinspection JSUnusedLocalSymbols -var logger = require('../logger'); - - -function PluginManager(options) { - ObjectWithListeners.call(this); - var self = this; - self.setProject(options.project); - self.setMap(options.map); - self.setElement(options.element); - self.setConfiguration(options.configuration); - self._plugins = []; - self._pluginOnResizeHandlers = {}; - - self.registerListenerType("onResize"); - self.addListener("onResize", function () { - var promises = []; - for (var i = 0; i < self._plugins.length; i++) { - promises.push(self._plugins[i].callListeners("onResize")); - } - return Promise.resolve(promises); - }); -} - -PluginManager.prototype = Object.create(ObjectWithListeners.prototype); -PluginManager.prototype.constructor = ObjectWithListeners; - -PluginManager.prototype.setProject = function (project) { - this._project = project; -}; -PluginManager.prototype.setMap = function (map) { - this._map = map; -}; -PluginManager.prototype.getMap = function () { - return this._map; -}; -PluginManager.prototype.setElement = function (element) { - this._element = element; -}; -PluginManager.prototype.getElement = function () { - return this._element; -}; - -PluginManager.prototype.setConfiguration = function (configuration) { - this._configuration = configuration; -}; - -PluginManager.prototype.getConfiguration = function () { - return this._configuration; -}; - -PluginManager.prototype.getPlugins = function () { - return this._plugins; -}; - -PluginManager.prototype.addPlugin = function (options) { - var self = this; - var tabData = self.createTabForPlugin(); - var plugin; - if (options instanceof Plugin) { - plugin = options; - plugin.setOptions({ - element: tabData.content, - configuration: self.getConfiguration(), - map: self.getMap() - }); - } else { - plugin = new Plugin({ - url: options.url, - element: tabData.content, - configuration: self.getConfiguration(), - map: self.getMap() - }); - plugin.addListener("onUnload", function () { - tabData.content.parentNode.removeChild(tabData.content); - tabData.title.parentNode.parentNode.removeChild(tabData.title.parentNode); - }); - } - self._plugins.push(plugin); - return plugin.load().then(function () { - tabData.title.innerHTML = plugin.getName(); - const tab = $(tabData.content); - tab.css('overflow', 'auto'); - var adjustHeight = function () { - tab.css('height', 'calc( 100vh - ' + $(tabData.content.parentNode).offset().top + 'px )'); - }; - - self._pluginOnResizeHandlers[plugin.getPluginId()] = adjustHeight; - GuiConnector.addWindowResizeEvent(adjustHeight); - adjustHeight(); - return self.adjustMinWidth(); - }).then(function () { - return plugin; - }); -}; - -PluginManager.prototype.createTabForPlugin = function () { - var self = this; - var tabData = self._tabData; - var guiUtils = new GuiUtils(self.getConfiguration()); - if (tabData === undefined) { - self.getElement().style.width = "300px"; - self.getElement().style.maxWidth = "600px"; - self.getElement().style.minWidth = "150px"; - self.getElement().style.height = "100%"; - self._tabData = guiUtils.createTabDiv({element: self.getElement(), id: "plugin_tab"}); - tabData = self._tabData; - $(tabData.content).css('position', 'relative'); - $(tabData.element).css('position', 'absolute'); - $(tabData.element).css('top', '0'); - } - return guiUtils.createTab({ - title: "", - content: "", - tabData: tabData - }); -}; -PluginManager.prototype.adjustMinWidth = function () { - var self = this; - var oldVal = self.getElement().style.minWidth; - var minWidth = 150; - var i; - for (i = 0; i < self._plugins.length; i++) { - var plugin = self._plugins[i]; - var value = plugin.getMinWidth(); - if (value > minWidth) { - minWidth = value; - } - } - var newVal = minWidth + "px"; - self.getElement().style.minWidth = newVal; - if (newVal !== oldVal) { - return self.callListeners("onResize"); - } else { - return Promise.resolve(); - } -}; - -PluginManager.prototype.removePlugin = function (plugin) { - var self = this; - var found = false; - for (var i = 0; i < self._plugins.length; i++) { - if (plugin === self._plugins[i]) { - self._plugins.splice(i, 1); - found = true; - } - } - if (!found) { - return Promise.reject(new Error("Plugin not registered")); - } - GuiConnector.removeWindowResizeEvent(self._pluginOnResizeHandlers[plugin.getPluginId()]); - return plugin.unload().then(function () { - return self.adjustMinWidth(); - }); -}; - -PluginManager.prototype.destroy = function () { - var self = this; - var promises = []; - var plugins = self._plugins; - for (var i = plugins.length - 1; i >= 0; i--) { - promises.push(self.removePlugin(plugins[i])); - } - return Promise.all(promises); -}; - - -module.exports = PluginManager; +"use strict"; + +var ObjectWithListeners = require('../ObjectWithListeners'); +var Plugin = require('./Plugin'); +var GuiUtils = require('../gui/leftPanel/GuiUtils'); +var GuiConnector = require('../GuiConnector'); +var InvalidArgumentError = require('../InvalidArgumentError'); +var isUrl = require('is-url'); + +var Promise = require("bluebird"); + +// noinspection JSUnusedLocalSymbols +var logger = require('../logger'); + + +function PluginManager(options) { + ObjectWithListeners.call(this); + var self = this; + self.setProject(options.project); + self.setMap(options.map); + self.setElement(options.element); + self.setConfiguration(options.configuration); + self._plugins = []; + self._pluginOnResizeHandlers = {}; + + self.registerListenerType("onResize"); + self.addListener("onResize", function () { + var promises = []; + for (var i = 0; i < self._plugins.length; i++) { + promises.push(self._plugins[i].callListeners("onResize")); + } + return Promise.resolve(promises); + }); +} + +PluginManager.prototype = Object.create(ObjectWithListeners.prototype); +PluginManager.prototype.constructor = ObjectWithListeners; + +PluginManager.prototype.setProject = function (project) { + this._project = project; +}; +PluginManager.prototype.setMap = function (map) { + this._map = map; +}; +PluginManager.prototype.getMap = function () { + return this._map; +}; +PluginManager.prototype.setElement = function (element) { + this._element = element; +}; +PluginManager.prototype.getElement = function () { + return this._element; +}; + +PluginManager.prototype.setConfiguration = function (configuration) { + this._configuration = configuration; +}; + +PluginManager.prototype.getConfiguration = function () { + return this._configuration; +}; + +PluginManager.prototype.getPlugins = function () { + return this._plugins; +}; + +PluginManager.prototype.addPlugin = function (options) { + var self = this; + var tabData = self.createTabForPlugin(); + var plugin; + if (options instanceof Plugin) { + plugin = options; + plugin.setOptions({ + element: tabData.content, + configuration: self.getConfiguration(), + map: self.getMap() + }); + } else { + if (!self.isValidUrl(options.url)) { + return Promise.reject(new InvalidArgumentError("url: '" + options.url + "' is invalid")); + } + plugin = new Plugin({ + url: options.url, + element: tabData.content, + configuration: self.getConfiguration(), + map: self.getMap() + }); + plugin.addListener("onUnload", function () { + tabData.content.parentNode.removeChild(tabData.content); + tabData.title.parentNode.parentNode.removeChild(tabData.title.parentNode); + }); + } + self._plugins.push(plugin); + return plugin.load().then(function () { + tabData.title.innerHTML = plugin.getName(); + const tab = $(tabData.content); + tab.css('overflow', 'auto'); + var adjustHeight = function () { + tab.css('height', 'calc( 100vh - ' + $(tabData.content.parentNode).offset().top + 'px )'); + }; + + self._pluginOnResizeHandlers[plugin.getPluginId()] = adjustHeight; + GuiConnector.addWindowResizeEvent(adjustHeight); + adjustHeight(); + return self.adjustMinWidth(); + }).then(function () { + return plugin; + }); +}; + +PluginManager.prototype.isValidUrl = function (url) { + return isUrl(url); +}; +PluginManager.prototype.createTabForPlugin = function () { + var self = this; + var tabData = self._tabData; + var guiUtils = new GuiUtils(self.getConfiguration()); + if (tabData === undefined) { + self.getElement().style.width = "300px"; + self.getElement().style.maxWidth = "600px"; + self.getElement().style.minWidth = "150px"; + self.getElement().style.height = "100%"; + self._tabData = guiUtils.createTabDiv({element: self.getElement(), id: "plugin_tab"}); + tabData = self._tabData; + $(tabData.content).css('position', 'relative'); + $(tabData.element).css('position', 'absolute'); + $(tabData.element).css('top', '0'); + } + return guiUtils.createTab({ + title: "", + content: "", + tabData: tabData + }); +}; +PluginManager.prototype.adjustMinWidth = function () { + var self = this; + var oldVal = self.getElement().style.minWidth; + var minWidth = 150; + var i; + for (i = 0; i < self._plugins.length; i++) { + var plugin = self._plugins[i]; + var value = plugin.getMinWidth(); + if (value > minWidth) { + minWidth = value; + } + } + var newVal = minWidth + "px"; + self.getElement().style.minWidth = newVal; + if (newVal !== oldVal) { + return self.callListeners("onResize"); + } else { + return Promise.resolve(); + } +}; + +PluginManager.prototype.removePlugin = function (plugin) { + var self = this; + var found = false; + for (var i = 0; i < self._plugins.length; i++) { + if (plugin === self._plugins[i]) { + self._plugins.splice(i, 1); + found = true; + } + } + if (!found) { + return Promise.reject(new Error("Plugin not registered")); + } + GuiConnector.removeWindowResizeEvent(self._pluginOnResizeHandlers[plugin.getPluginId()]); + return plugin.unload().then(function () { + return self.adjustMinWidth(); + }); +}; + +PluginManager.prototype.destroy = function () { + var self = this; + var promises = []; + var plugins = self._plugins; + for (var i = plugins.length - 1; i >= 0; i--) { + promises.push(self.removePlugin(plugins[i])); + } + return Promise.all(promises); +}; + + +module.exports = PluginManager; diff --git a/frontend-js/src/test/js/plugin/PluginManager-test.js b/frontend-js/src/test/js/plugin/PluginManager-test.js index 8a289f88e6fef708a6b5a16014b2aca9ddd22d13..fd1f389da7423c828c0a2febb42d23df4b5ec117 100644 --- a/frontend-js/src/test/js/plugin/PluginManager-test.js +++ b/frontend-js/src/test/js/plugin/PluginManager-test.js @@ -2,6 +2,7 @@ require("../mocha-config"); +var InvalidArgumentError = require('../../../main/js/InvalidArgumentError'); var Plugin = require('../../../main/js/plugin/Plugin'); var PluginManager = require('../../../main/js/plugin/PluginManager'); var ProxyAccessPlugin = require('./ProxyAccessPlugin'); @@ -19,6 +20,13 @@ describe('PluginManager', function () { element: testDiv }; }; + var createPluginManager = function () { + var result = new PluginManager(createParams()); + result.isValidUrl = function () { + return true; + }; + return result; + }; it('constructor', function () { var manager = new PluginManager(createParams()); assert.ok(manager); @@ -26,25 +34,25 @@ describe('PluginManager', function () { }); it('getPlugins', function () { - var manager = new PluginManager(createParams()); + var manager = createPluginManager(); assert.equal(0, manager.getPlugins().length); }); describe('addPlugin', function () { it('default', function () { - var manager = new PluginManager(createParams()); + var manager = createPluginManager(); return manager.addPlugin({url: "./testFiles/plugin/empty.js"}).then(function () { assert.equal(1, manager.getPlugins().length); }); }); it('with min width', function () { - var manager = new PluginManager(createParams()); + var manager = createPluginManager(); return manager.addPlugin({url: "./testFiles/plugin/min-width.js"}).then(function () { assert.equal("200px", $(manager.getElement()).css("min-width")); }); }); it('with onResize listener', function () { - var manager = new PluginManager(createParams()); + var manager = createPluginManager(); var plugin = new ProxyAccessPlugin({}); var listenerCalled = false; return manager.addPlugin(plugin).then(function () { @@ -59,7 +67,7 @@ describe('PluginManager', function () { }); }); it('after removal', function () { - var manager = new PluginManager(createParams()); + var manager = createPluginManager(); return manager.addPlugin({url: "./testFiles/plugin/empty.js"}).then(function (plugin) { return manager.removePlugin(plugin); }).then(function () { @@ -68,11 +76,28 @@ describe('PluginManager', function () { assert.equal(1, manager.getPlugins().length); }); }); + + + }); + + describe('isValidUrl', function () { + it('invalid url 1', function () { + var manager = new PluginManager(createParams()); + assert.notOk(manager.isValidUrl("")); + }); + it('invalid undefined', function () { + var manager = new PluginManager(createParams()); + assert.notOk(manager.isValidUrl(undefined)); + }); + it('valid', function () { + var manager = new PluginManager(createParams()); + assert.ok("http://onet.pl/"); + }); }); describe('removePlugin', function () { it('default', function () { - var manager = new PluginManager(createParams()); + var manager = createPluginManager(); return manager.addPlugin({url: "testFiles/plugin/empty.js"}).then(function (plugin) { return manager.removePlugin(plugin); }).then(function () { @@ -80,7 +105,7 @@ describe('PluginManager', function () { }); }); it('removing non existing plugin', function () { - var manager = new PluginManager(createParams()); + var manager = createPluginManager(); var plugin = new Plugin({url: "testFiles/plugin/empty.js"}); return manager.removePlugin(plugin).then(function () { assert.notOk("Error expected");