commit 5c33d5cbbaf3507fdb5587efabb0e4993bdebbab
Author: Pavel Fidranský <fidransky@outlook.com>
Date:   Tue Oct 23 21:07:10 2018 +0200

    reworked EdgePopover and VertexPopover to extend newly created Popover JS class

diff --git a/sources/src/main/webapp/css/main.css b/sources/src/main/webapp/css/main.css
index e46ba95..af97c79 100644
--- a/sources/src/main/webapp/css/main.css
+++ b/sources/src/main/webapp/css/main.css
@@ -411,7 +411,7 @@ form input[type="checkbox"] {
 	border-bottom: 1px solid #c8cbcc;
 }
 
-.popover-content {
+.popover-body {
 	max-height: 400px;
 	overflow: auto;
 	padding: 0 0.5em 0.5em 0.5em;
diff --git a/sources/src/main/webapp/js/components/edge.js b/sources/src/main/webapp/js/components/edge.js
index 95f28d0..4f8fc2a 100644
--- a/sources/src/main/webapp/js/components/edge.js
+++ b/sources/src/main/webapp/js/components/edge.js
@@ -262,8 +262,8 @@ function Edge(props) {
 	 * @param {Event} e Click event.
 	 */
 	function click(e) {
-		app.viewportComponent.edgePopoverComponent.setContent(props.subedgeInfo);
-		app.viewportComponent.edgePopoverComponent.setPosition(new Coordinates(e.clientX, e.clientY));
+		app.viewportComponent.edgePopoverComponent.body = props.subedgeInfo;
+		app.viewportComponent.edgePopoverComponent.position = new Coordinates(e.clientX, e.clientY);
 		app.viewportComponent.edgePopoverComponent.open();
 
 		// unhighlight other edges
diff --git a/sources/src/main/webapp/js/components/edgePopover.js b/sources/src/main/webapp/js/components/edgePopover.js
index f1406e4..3e946cf 100644
--- a/sources/src/main/webapp/js/components/edgePopover.js
+++ b/sources/src/main/webapp/js/components/edgePopover.js
@@ -1,88 +1,42 @@
 /**
  * Class representing a popover revealed on edge click to display its compatibility information.
  * @see Edge
- * @constructor
  */
-function EdgePopover() {
-	var rootElement;
-	var detailsListElement;
-
-	/**
-	 * Sets the contents of the popover.
-	 * @param {array} subedgeInfoList List of various edge information.
-	 */
-	this.setContent = function(subedgeInfoList) {
-		if (subedgeInfoList.length === 0) return;
-
-		subedgeInfoList.filter(function(subedgeInfo) {
-			return subedgeInfo.attributes.length > 0;
-		}).forEach(function(subedgeInfo) {
-			var listItem = DOM.createHtmlElement('li');
-			listItem.appendChild(DOM.createTextElement(app.archetype.edge[subedgeInfo.archetype].name));
-
-			var sublist = DOM.createHtmlElement('ul');
-			listItem.appendChild(sublist);
-
-			detailsListElement.appendChild(listItem);
-
-			subedgeInfo.attributes.forEach(function(attribute) {
-				sublist.appendChild(new Attribute(attribute).render());
-			});
-		});
-	};
-
+class EdgePopover extends Popover {
 	/**
-	 * Moves the popover to the coordinates.
-	 * @param {Coordinates} coords Coordinates to display the popover at.
+	 * @inheritdoc
 	 */
-	this.setPosition = function(coords) {
-		rootElement.style.top = coords.y + 'px';
-		rootElement.style.left = coords.x + 'px';
-	};
+	render() {
+		super.render();
 
-	/**
-	 * Opens the popover.
-	 */
-	this.open = function() {
-		rootElement.classList.remove('hidden');
-	};
+		this._titleElement.innerText = 'Edge details';
 
-	/**
-	 * Closes the popover.
-	 */
-	this.close = function() {
-		rootElement.classList.add('hidden');
+		this._detailsListElement = DOM.h('ul');
+		this._bodyElement.appendChild(this._detailsListElement);
 
-		detailsListElement.innerHTML = '';
-	};
+		return this._rootElement;
+	}
 
 	/**
-	 * Creates a new DOM element representing the popover in memory. Binds user interactions to local handler functions.
-	 * @returns {Element} HTML DOM element.
+	 * Sets the contents of the popover.
+	 * @param {array} subedgeInfoList List of various edge information.
 	 */
-	this.render = function() {
-		rootElement = DOM.createHtmlElement('div', {
-			'class': 'popover edge-popover hidden',
-		});
-		rootElement.addEventListener('wheel', Utils.stopPropagation);
-		rootElement.addEventListener('mousedown', Utils.stopPropagation);
-		rootElement.addEventListener('mouseleave', this.close.bind(this));
+	set body(subedgeInfoList) {
+		if (subedgeInfoList.length === 0) return;
 
-		var popoverTitle = DOM.createHtmlElement('span', {
-			'class': 'popover-title',
-		});
-		popoverTitle.appendChild(document.createTextNode('Edge details'));
-		rootElement.appendChild(popoverTitle);
+		subedgeInfoList.filter(subedgeInfo => {
+			return subedgeInfo.attributes.length > 0;
+		}).forEach(subedgeInfo => {
+			const sublistElement = DOM.h('ul');
+			subedgeInfo.attributes.forEach(attribute => {
+				sublistElement.appendChild(new Attribute(attribute).render());
+			});
 
-		var popoverContent = DOM.createHtmlElement('div', {
-			'class': 'popover-content',
+			this._detailsListElement.appendChild(DOM.h('li', {
+				innerText: app.archetype.edge[subedgeInfo.archetype].name,
+			}, [
+				sublistElement,
+			]));
 		});
-		rootElement.appendChild(popoverContent);
-
-		detailsListElement = DOM.createHtmlElement('ul');
-		popoverContent.appendChild(detailsListElement);
-
-		return rootElement;
-	};
-
+	}
 }
diff --git a/sources/src/main/webapp/js/components/vertex.js b/sources/src/main/webapp/js/components/vertex.js
index 8eebb7b..e7fc17e 100644
--- a/sources/src/main/webapp/js/components/vertex.js
+++ b/sources/src/main/webapp/js/components/vertex.js
@@ -731,8 +731,9 @@ function Vertex(props) {
 	function archetypeClick(e) {
 		e.stopPropagation();
 
-		app.viewportComponent.vertexPopoverComponent.setContent(this.name + ` (${app.archetype.vertex[this.archetype].name})`, props.attributes);
-		app.viewportComponent.vertexPopoverComponent.setPosition(new Coordinates(e.clientX, e.clientY));
+		app.viewportComponent.vertexPopoverComponent.title = this.name + ` (${app.archetype.vertex[this.archetype].name})`;
+		app.viewportComponent.vertexPopoverComponent.body = props.attributes;
+		app.viewportComponent.vertexPopoverComponent.position = new Coordinates(e.clientX, e.clientY);
 		app.viewportComponent.vertexPopoverComponent.open();
 	}
 	
diff --git a/sources/src/main/webapp/js/components/vertexPopover.js b/sources/src/main/webapp/js/components/vertexPopover.js
index ef2692d..27779dd 100644
--- a/sources/src/main/webapp/js/components/vertexPopover.js
+++ b/sources/src/main/webapp/js/components/vertexPopover.js
@@ -1,78 +1,39 @@
 /**
  * Class representing a popover revealed on vertex interface symbol click to display its attributes.
  * @see Vertex
- * @constructor
  */
-function VertexPopover() {
-	var rootElement;
-	var popoverTitle;
-	var detailsListElement;
-
+class VertexPopover extends Popover {
 	/**
-	 * Sets the contents of the popover.
-	 * @param {string} name Title of the popover.
-	 * @param {array} attributeList List of attributes.
+	 * @inheritdoc
 	 */
-	this.setContent = function(name, attributeList) {
-		popoverTitle.innerText = name;
-
-		if (attributeList.length === 0) return;
-
-		attributeList.forEach(function(attribute) {
-			detailsListElement.appendChild(new Attribute(attribute).render());
-		});
-	};
+	render() {
+		super.render();
 
-	/**
-	 * Moves the popover to the coordinates.
-	 * @param {Coordinates} coords Coordinates to display the popover at.
-	 */
-	this.setPosition = function(coords) {
-		rootElement.style.top = coords.y + 'px';
-		rootElement.style.left = coords.x + 'px';
-	};
+		this._detailsListElement = DOM.h('ul');
+		this._bodyElement.appendChild(this._detailsListElement);
 
-	/**
-	 * Opens the popover.
-	 */
-	this.open = function() {
-		rootElement.classList.remove('hidden');
-	};
+		return this._rootElement;
+	}
 
 	/**
-	 * Closes the popover.
+	 * Sets the title of the popover.
+	 * @public
+	 * @param {array} attributeList List of attributes.
 	 */
-	this.close = function() {
-		rootElement.classList.add('hidden');
-
-		detailsListElement.innerHTML = '';
-	};
+	set title(name) {
+		this._titleElement.innerText = name;
+	}
 
 	/**
-	 * Creates a new DOM element representing the popover in memory. Binds user interactions to local handler functions.
-	 * @returns {Element} HTML DOM element.
+	 * Sets the body of the popover.
+	 * @public
+	 * @param {array} attributeList List of attributes.
 	 */
-	this.render = function() {
-		rootElement = DOM.createHtmlElement('div', {
-			'class': 'popover vertex-popover hidden',
-		});
-		rootElement.addEventListener('wheel', Utils.stopPropagation);
-		rootElement.addEventListener('mousedown', Utils.stopPropagation);
-		rootElement.addEventListener('mouseleave', this.close.bind(this));
-
-		popoverTitle = DOM.createHtmlElement('span', {
-			'class': 'popover-title',
-		});
-		rootElement.appendChild(popoverTitle);
+	set body(attributeList) {
+		if (attributeList.length === 0) return;
 
-		var popoverContent = DOM.createHtmlElement('div', {
-			'class': 'popover-content',
+		attributeList.forEach(attribute => {
+			this._detailsListElement.appendChild(new Attribute(attribute).render());
 		});
-		rootElement.appendChild(popoverContent);
-
-		detailsListElement = DOM.createHtmlElement('ul');
-		popoverContent.appendChild(detailsListElement);
-
-		return rootElement;
-	};
-}
\ No newline at end of file
+	}
+}
