commit 92a538e1c8b479140b4c07b48ad6cd38790ce926
Author: Pavel Fidranský <fidransky@outlook.com>
Date:   Tue Oct 23 21:02:02 2018 +0200

    created reusable ModalWindow, Popover and Popup components as ES6 classes

diff --git a/sources/src/main/webapp/js/components/generic/modalWindow.js b/sources/src/main/webapp/js/components/generic/modalWindow.js
new file mode 100644
index 0000000..150fe05
--- /dev/null
+++ b/sources/src/main/webapp/js/components/generic/modalWindow.js
@@ -0,0 +1,79 @@
+/**
+ * Class representing a modal window.
+ */
+class ModalWindow {
+	/**
+	 * Creates a new HTML DOM element representing the modal window. Binds user interactions to local handler functions.
+	 * @public
+	 * @returns newly created HTML DOM element
+	 */
+	render() {
+		this._bodyElement = DOM.h('div', {
+			class: 'modal-body',
+		});
+
+		this._rootElement = DOM.h('div', {
+			class: 'modal',
+			hidden: 'hidden',
+			onClick: this.close.bind(this),
+		}, [
+			DOM.h('div', {
+				class: 'modal-content',
+				onClick: Utils.stopPropagation,
+			}, [
+				DOM.h('button', {
+					class: 'close-button button',
+					innerText: '×',
+					onClick: this.close.bind(this),
+				}),
+				this._bodyElement,
+			]),
+		]);
+
+		return this._rootElement;
+	}
+
+	/**
+	 * @public
+	 * @returns {boolean} true if the DOM element has been instantiated using render() method, otherwise false
+	 */
+	get isInitialized() {
+		return Utils.isDefined(this._rootElement);
+	}
+
+	/**
+	 * @public
+	 * @returns {boolean} true if the modal window is visible at the moment, otherwise false
+	 */
+	get isVisible() {
+		return this._rootElement.hasAttribute('hidden');
+	}
+
+	/**
+	 * Opens the modal window.
+	 * @public
+	 */
+	open() {
+		this._rootElement.removeAttribute('hidden');
+	}
+
+	/**
+	 * Closes the modal window.
+	 * @public
+	 */
+	close() {
+		this._rootElement.setAttribute('hidden', 'hidden');
+	}
+
+	/**
+	 * Toggles visibility of the modal window.
+	 * @public
+	 */
+	toggle() {
+		if (this.isVisible) {
+			this.open();
+		} else {
+			this.close();
+		}
+	}
+}
diff --git a/sources/src/main/webapp/js/components/generic/popover.js b/sources/src/main/webapp/js/components/generic/popover.js
new file mode 100644
index 0000000..324981f
--- /dev/null
+++ b/sources/src/main/webapp/js/components/generic/popover.js
@@ -0,0 +1,74 @@
+/**
+ * Class representing a popover.
+ */
+class Popover {
+	/**
+	 * Creates a new HTML DOM element representing the popover. Binds user interactions to local handler functions.
+	 * @public
+	 * @returns newly created HTML DOM element
+	 */
+	render() {
+		this._titleElement = DOM.h('span', {
+			class: 'popover-title',
+		});
+
+		this._bodyElement = DOM.h('div', {
+			class: 'popover-body',
+		});
+
+		this._rootElement = DOM.h('div', {
+			class: 'popover',
+			hidden: 'hidden',
+			onWheel: Utils.stopPropagation,
+			onMouseDown: Utils.stopPropagation,
+			onMouseLeave: this.close.bind(this),
+		}, [
+			this._titleElement,
+			this._bodyElement,
+		]);
+
+		return this._rootElement;
+	}
+
+	/**
+	 * Moves the popover to the coordinates.
+	 * @public
+	 * @param {Coordinates} coords Coordinates to display the popover at.
+	 */
+	set position(coords) {
+		this._rootElement.style.top = coords.y + 'px';
+		this._rootElement.style.left = coords.x + 'px';
+	}
+
+	/**
+	 * @public
+	 * @returns {boolean} true if the DOM element has been instantiated using render() method, otherwise false
+	 */
+	get isInitialized() {
+		return Utils.isDefined(this._rootElement);
+	}
+
+	/**
+	 * @public
+	 * @returns {boolean} true if the modal window is visible at the moment, otherwise false
+	 */
+	get isVisible() {
+		return this._rootElement.hasAttribute('hidden');
+	}
+
+	/**
+	 * Opens the modal window.
+	 * @public
+	 */
+	open() {
+		this._rootElement.removeAttribute('hidden');
+	}
+
+	/**
+	 * Closes the modal window.
+	 * @public
+	 */
+	close() {
+		this._rootElement.setAttribute('hidden', 'hidden');
+	}
+}
diff --git a/sources/src/main/webapp/js/components/generic/popup.js b/sources/src/main/webapp/js/components/generic/popup.js
new file mode 100644
index 0000000..144d408
--- /dev/null
+++ b/sources/src/main/webapp/js/components/generic/popup.js
@@ -0,0 +1,54 @@
+class Popup {
+	/**
+	 * @public
+	 * @returns {HTMLElement} newly created HTML DOM element
+	 */
+	render() {
+		this._rootElement = DOM.h('div', {
+			class: 'popup',
+			hidden: 'hidden',
+		});
+
+		return this._rootElement;
+	}
+
+	/**
+	 * @public
+	 * @returns {boolean} true if the DOM element has been instantiated using render() method, otherwise false
+	 */
+	get isInitialized() {
+		return Utils.isDefined(this._rootElement);
+	}
+
+	/**
+	 * @returns {boolean} true if the popup is visible at the moment, otherwise false
+	 */
+	get isVisible() {
+		return this._rootElement.hasAttribute('hidden');
+	}
+
+	/**
+	 * Opens the popup.
+	 */
+	open() {
+		this._rootElement.removeAttribute('hidden');
+	}
+
+	/**
+	 * Closes the popup.
+	 */
+	close() {
+		this._rootElement.setAttribute('hidden', 'hidden');
+	}
+
+	/**
+	 * Toggles visibility of the popup.
+	 */
+	toggle() {
+		if (this.isVisible) {
+			this.open();
+		} else {
+			this.close();
+		}
+	}
+}
