diff --git a/src/config.xml b/src/config.xml index 8c6aece..2b9f029 100644 --- a/src/config.xml +++ b/src/config.xml @@ -1,5 +1,7 @@ - + + 2 +
Panel aarranz@conwet.com @@ -20,11 +22,19 @@ + + + + + + + + @@ -32,5 +42,9 @@ + + - - + + + +

+

+ + \ No newline at end of file diff --git a/src/js/main.js b/src/js/main.js index 74e59ac..0cd6bac 100644 --- a/src/js/main.js +++ b/src/js/main.js @@ -21,111 +21,190 @@ "use strict"; - const repaint = function repaint() { - var height, width, message, next, min; - - height = MashupPlatform.widget.context.get('heightInPixels'); - width = MashupPlatform.widget.context.get('widthInPixels'); - message = document.getElementById('message'); - - document.body.style.fontSize = (height * 0.7) + 'px'; - document.body.style.lineHeight = height + 'px'; - - message.style.height = height + 'px'; - next = Number(MashupPlatform.prefs.get('max-height')) / 100; - min = Number(MashupPlatform.prefs.get('min-height')) / 100; - while ((message.offsetWidth > width || message.offsetHeight > height) && next >= min) { - document.body.style.fontSize = Math.floor(height * next) + 'px'; - next -= 0.05; - } - if ((message.offsetWidth > width || message.offsetHeight > height)) { - document.body.style.fontSize = Math.floor(height * min) + 'px'; + class Widget { + constructor(MashupPlatform, shadowDOM, _) { + this.MashupPlatform = MashupPlatform; + this.shadowDOM = shadowDOM; + + this.body = this.shadowDOM.querySelector('body'); + + this.init(); + this.repaint(); } - }; - - const parseInputEndpointData = function parseInputEndpointData(data) { - if (typeof data === "string") { - try { - data = JSON.parse(data); - } catch (e) { - return data; + + repaint() { + var height, width, backgroundColor, textColor, barColor, message, next, min, title, minmaxContainer, + leftTagText, rightTagText, leftTag, rightTag, minVal, maxVal, barIndicator, bar; + + height = this.body.offsetHeight; + width = this.body.offsetWidth; + backgroundColor = this.MashupPlatform.prefs.get('background-color'); + textColor = this.MashupPlatform.prefs.get('text-color'); + barColor = this.MashupPlatform.prefs.get('bar-color'); + leftTagText = this.MashupPlatform.prefs.get('left-tag-text'); + rightTagText = this.MashupPlatform.prefs.get('right-tag-text'); + minVal = this.MashupPlatform.prefs.get('min-value'); + maxVal = this.MashupPlatform.prefs.get('max-value'); + message = this.shadowDOM.getElementById('message'); + title = this.shadowDOM.getElementById('title'); + minmaxContainer = this.shadowDOM.getElementById('minmax-container'); + leftTag = this.shadowDOM.getElementById('bar-tag-left'); + rightTag = this.shadowDOM.getElementById('bar-tag-right'); + barIndicator = this.shadowDOM.getElementById('bar-indicator'); + bar = this.shadowDOM.getElementById('bar'); + + // Try to parse min and max values to check if they are numbers + if (minVal.trim() != "" && maxVal.trim() != "" && !isNaN(minVal) && !isNaN(maxVal) + && parseFloat(minVal) < parseFloat(maxVal)) { + minmaxContainer.style.display = ""; + leftTag.textContent = leftTagText; + rightTag.textContent = rightTagText; + + height -= minmaxContainer.offsetHeight + parseInt(window.getComputedStyle(minmaxContainer)["margin-bottom"], 10) + + parseInt(window.getComputedStyle(minmaxContainer)["margin-top"], 10); + } else { + minmaxContainer.style.display = "none"; } - } - return data; - }; + title.textContent = this.MashupPlatform.prefs.get('title'); + + this.body.style.color = this.parseColor(textColor, "#000000"); + this.body.style.backgroundColor = this.parseColor(backgroundColor, "#FFFFFF"); + leftTag.style.color = this.parseColor(textColor, "#000000"); + rightTag.style.color = this.parseColor(textColor, "#000000"); + barIndicator.style.backgroundColor = this.parseColor(textColor, "#000000"); + bar.style.backgroundColor = this.parseColor(barColor, "#000000"); + + height -= title.offsetHeight; - const processIncomingData = function processIncomingData(data) { - var message, unit, decimals, default_unit, pow; + message.style.fontSize = (height * 0.7) + 'px'; + this.body.style.lineHeight = height + 'px'; - data = parseInputEndpointData(data); - if (data == null || ["number", "string", "boolean"].indexOf(typeof data) !== -1) { - data = { - value: data - }; + next = Number(this.MashupPlatform.prefs.get('max-height')) / 100; + min = Number(this.MashupPlatform.prefs.get('min-height')) / 100; + while ((message.offsetWidth > width || message.offsetHeight > height) && next >= min) { + message.style.fontSize = Math.floor(height * next) + 'px'; + next -= 0.05; + } + if ((message.offsetWidth > width || message.offsetHeight > height)) { + message.style.fontSize = Math.floor(height * min) + 'px'; + } } - decimals = parseInt(MashupPlatform.prefs.get('decimals'), 10); - if (isNaN(decimals) || decimals < 0) { - decimals = 0; + + parseInputEndpointData(data) { + if (typeof data === "string") { + try { + data = JSON.parse(data); + } catch (e) { + return data; + } + } + + return data; } - message = document.getElementById('message'); - if (data.value == null) { - message.textContent = MashupPlatform.prefs.get('default-value'); - } else if (typeof data.value === 'number') { - pow = Math.pow(10, decimals); - data.value = Math.round((pow * data.value).toFixed(decimals)) / pow; - message.textContent = data.value; - } else { - message.textContent = data.value; + processIncomingData(data) { + var message, unit, decimals, default_unit, pow, minVal, maxVal, barIndicator, percentage; + + minVal = this.MashupPlatform.prefs.get('min-value'); + maxVal = this.MashupPlatform.prefs.get('max-value'); + barIndicator = this.shadowDOM.getElementById('bar-indicator'); + + data = this.parseInputEndpointData(data); + if (data == null || ["number", "string", "boolean"].indexOf(typeof data) !== -1) { + data = { + value: data + }; + } + decimals = parseInt(this.MashupPlatform.prefs.get('decimals'), 10); + if (isNaN(decimals) || decimals < 0) { + decimals = 0; + } + + message = this.shadowDOM.getElementById('message'); + if (data.value == null) { + message.textContent = this.MashupPlatform.prefs.get('default-value'); + } else if (typeof data.value === 'number') { + if (minVal.trim() != "" && maxVal.trim() != "" && !isNaN(minVal) && !isNaN(maxVal) + && parseFloat(minVal) < parseFloat(maxVal)) { + percentage = (data.value - minVal) / (maxVal - minVal); + if (percentage < 0) { + percentage = 0; + } else if (percentage > 1) { + percentage = 1; + } + + barIndicator.style.left = "calc(" + percentage * 100 + "% - (" + percentage + "*" + + barIndicator.offsetWidth + "px))"; + } + + pow = Math.pow(10, decimals); + data.value = Math.round((pow * data.value).toFixed(decimals)) / pow; + message.textContent = data.value; + } else { + message.textContent = data.value; + } + + unit = document.createElement('span'); + default_unit = this.MashupPlatform.prefs.get('default-unit'); + if (data.unit != null) { + unit.textContent = data.unit; + message.appendChild(unit); + } else if (!("unit" in data) && default_unit.trim() != "") { + unit.textContent = default_unit; + message.appendChild(unit); + } + + this.repaint(); } - unit = document.createElement('span'); - default_unit = MashupPlatform.prefs.get('default-unit'); - if (data.unit != null) { - unit.textContent = data.unit; - message.appendChild(unit); - } else if (!("unit" in data) && default_unit.trim() != "") { - unit.textContent = default_unit; - message.appendChild(unit); + parseColor(color, default_color) { + const colorRegex = /^#[0-9a-fA-F]{8}$/i; + + if (colorRegex.test(color)) { + return "rgba(" + parseInt(color.substr(1, 2), 16) + "," + + parseInt(color.substr(3, 2), 16) + "," + + parseInt(color.substr(5, 2), 16) + "," + + (parseInt(color.substr(7, 2), 16) / 255) + ")"; + } else { + this.MashupPlatform.widget.log("Invalid color: " + color, this.MashupPlatform.log.WARN); + return default_color; + } } - repaint(); - }; - const init = function init() { - MashupPlatform.wiring.registerCallback('textinput', processIncomingData); + init() { + this.MashupPlatform.wiring.registerCallback('textinput', this.processIncomingData.bind(this)); - MashupPlatform.widget.context.registerCallback(function (newValues) { - if ("heightInPixels" in newValues || "widthInPixels" in newValues) { - repaint(); - } - }.bind(this)); + this.MashupPlatform.widget.context.registerCallback(function (newValues) { + if ("heightInPixels" in newValues || "widthInPixels" in newValues) { + this.repaint(); + } + }.bind(this)); + + // Sometimes the widget is not correctly resized when the page is loaded + // so we force a repaint after a timeout + setTimeout(this.repaint.bind(this), 500); - /* Initial content */ + this.MashupPlatform.prefs.registerCallback(function (_) { + this.repaint(); + }.bind(this)); - var message = document.getElementById('message'); - message.textContent = MashupPlatform.prefs.get('default-value'); + /* Initial content */ - var default_unit = MashupPlatform.prefs.get('default-unit'); - if (default_unit.trim() != "") { - var unit = document.createElement('span'); - unit.textContent = default_unit; - message.appendChild(unit); + var message = this.shadowDOM.getElementById('message'); + var title = this.shadowDOM.getElementById('title'); + message.textContent = this.MashupPlatform.prefs.get('default-value'); + title.textContent = this.MashupPlatform.prefs.get('title'); + + var default_unit = this.MashupPlatform.prefs.get('default-unit'); + if (default_unit.trim() != "") { + var unit = document.createElement('span'); + unit.textContent = default_unit; + message.appendChild(unit); + } } - }; - - /* test-code */ - window.init = init; - window.processIncomingData = processIncomingData; - window.repaint = repaint; - /* end-test-code */ - - /* TODO - * this if is required for testing, but we have to search a cleaner way - */ - if (window.MashupPlatform != null) { - init(); - repaint(); } + window.CoNWeT_Panel = Widget; + })(); diff --git a/tests/js/PanelWidgetSpec.js b/tests/js/PanelWidgetSpec.js index a1e2e57..5bd7a41 100644 --- a/tests/js/PanelWidgetSpec.js +++ b/tests/js/PanelWidgetSpec.js @@ -14,16 +14,16 @@ * limitations under the License. */ -/* global MashupPlatform, MockMP, init, processIncomingData, repaint */ +/* global MashupPlatform, MockMP, shadowDOM, widget */ (function () { "use strict"; - const HTML_FIXTURE_CODE = '

'; + const HTML_FIXTURE_CODE = '

'; const clearDocument = function clearDocument() { - var elements = document.querySelectorAll('body > *:not(.jasmine_html-reporter)'); + var elements = shadowDOM.querySelector("body").children; for (var i = 0; i < elements.length; i++) { elements[i].parentElement.removeChild(elements[i]); @@ -36,19 +36,38 @@ window.MashupPlatform = new MockMP({ type: 'widget', prefs: { + 'title': 'Panel Widget', 'default-value': '--', 'default-unit': '', 'max-height': 60, 'min-height': 10, - 'decimals': 1 + 'decimals': 1, + 'background-color': '#FFFFFFFF', + 'text-color': '#000000FF', + 'bar-color': '#DDDDDDFF', + 'min-value': '', + 'max-value': '', + 'left-tag-text': '', + 'right-tag-text': '' }, inputs: ['textinput'] }); + + let div = document.createElement('div'); + div.id = 'widget'; + document.body.appendChild(div); + div.attachShadow({mode: 'open'}); + let shadowBody = document.createElement('body'); + div.shadowRoot.appendChild(shadowBody); + window.shadowDOM = div.shadowRoot; + shadowDOM.querySelector("body").innerHTML += HTML_FIXTURE_CODE + + window.widget = new window.CoNWeT_Panel(MashupPlatform, shadowDOM, undefined); }); beforeEach(() => { clearDocument(); - document.body.innerHTML += HTML_FIXTURE_CODE; + shadowDOM.querySelector("body").innerHTML += HTML_FIXTURE_CODE; MashupPlatform.reset(); }); @@ -57,20 +76,20 @@ describe("default-value", () => { it("should work with the default value", () => { - spyOn(window, "repaint"); - init(); + spyOn(widget, "repaint"); + widget.init(); - expect(repaint).not.toHaveBeenCalled(); - expect(document.getElementById('message').textContent).toBe("--"); + expect(widget.repaint).not.toHaveBeenCalled(); + expect(shadowDOM.getElementById('message').textContent).toBe("--"); }); it("should work with other values", () => { MashupPlatform.prefs.set("default-value", "n/a"); - spyOn(window, "repaint"); - init(); + spyOn(widget, "repaint"); + widget.init(); - expect(repaint).not.toHaveBeenCalled(); - expect(document.getElementById('message').textContent).toBe("n/a"); + expect(widget.repaint).not.toHaveBeenCalled(); + expect(shadowDOM.getElementById('message').textContent).toBe("n/a"); }); }); @@ -78,20 +97,20 @@ describe("default-unit", () => { it("should work with the default value", () => { - spyOn(window, "repaint"); - init(); + spyOn(widget, "repaint"); + widget.init(); - expect(repaint).not.toHaveBeenCalled(); - expect(document.getElementById('message').textContent).toBe("--"); + expect(widget.repaint).not.toHaveBeenCalled(); + expect(shadowDOM.getElementById('message').textContent).toBe("--"); }); it("should work with other values", () => { MashupPlatform.prefs.set("default-unit", "ºC"); - spyOn(window, "repaint"); - init(); + spyOn(widget, "repaint"); + widget.init(); - expect(repaint).not.toHaveBeenCalled(); - expect(document.getElementById('message').textContent).toBe("--ºC"); + expect(widget.repaint).not.toHaveBeenCalled(); + expect(shadowDOM.getElementById('message').textContent).toBe("--ºC"); }); }); @@ -99,32 +118,32 @@ describe("decimals", () => { it("should work with the default value", () => { - spyOn(window, "repaint"); - init(); + spyOn(widget, "repaint"); + widget.init(); - processIncomingData(5.12); + widget.processIncomingData(5.12); - expect(document.getElementById('message').textContent).toBe("5.1"); + expect(shadowDOM.getElementById('message').textContent).toBe("5.1"); }); it("should work with other values", () => { MashupPlatform.prefs.set("decimals", "2"); - spyOn(window, "repaint"); - init(); + spyOn(widget, "repaint"); + widget.init(); - processIncomingData(5.12); + widget.processIncomingData(5.12); - expect(document.getElementById('message').textContent).toBe("5.12"); + expect(shadowDOM.getElementById('message').textContent).toBe("5.12"); }); it("should handle invalid decimal values", () => { MashupPlatform.prefs.set("decimals", "-1"); - spyOn(window, "repaint"); - init(); + spyOn(widget, "repaint"); + widget.init(); - processIncomingData(5.12); + widget.processIncomingData(5.12); - expect(document.getElementById('message').textContent).toBe("5"); + expect(shadowDOM.getElementById('message').textContent).toBe("5"); }); }); @@ -136,31 +155,31 @@ describe("basic values (plain)", () => { it("number", () => { - init(); - processIncomingData(5); + widget.init(); + widget.processIncomingData(5); - expect(document.getElementById('message').textContent).toBe("5"); + expect(shadowDOM.getElementById('message').textContent).toBe("5"); }); it("string", () => { - init(); - processIncomingData("new content"); + widget.init(); + widget.processIncomingData("new content"); - expect(document.getElementById('message').textContent).toBe("new content"); + expect(shadowDOM.getElementById('message').textContent).toBe("new content"); }); it("boolean", () => { - init(); - processIncomingData(true); + widget.init(); + widget.processIncomingData(true); - expect(document.getElementById('message').textContent).toBe("true"); + expect(shadowDOM.getElementById('message').textContent).toBe("true"); }); it("null", () => { - init(); - processIncomingData(null); + widget.init(); + widget.processIncomingData(null); - expect(document.getElementById('message').textContent).toBe("--"); + expect(shadowDOM.getElementById('message').textContent).toBe("--"); }); }); @@ -168,32 +187,32 @@ describe("basic values", () => { it("number", () => { - init(); - processIncomingData({value: 5}); + widget.init(); + widget.processIncomingData({value: 5}); - expect(document.getElementById('message').textContent).toBe("5"); + expect(shadowDOM.getElementById('message').textContent).toBe("5"); }); it("string", () => { - init(); - processIncomingData({value: "new content"}); + widget.init(); + widget.processIncomingData({value: "new content"}); - expect(document.getElementById('message').textContent).toBe("new content"); + expect(shadowDOM.getElementById('message').textContent).toBe("new content"); }); it("boolean", () => { - init(); - processIncomingData({value: true}); + widget.init(); + widget.processIncomingData({value: true}); - expect(document.getElementById('message').textContent).toBe("true"); + expect(shadowDOM.getElementById('message').textContent).toBe("true"); }); it("null", () => { MashupPlatform.prefs.set("default-unit", "ºC"); - init(); - processIncomingData({value: null}); + widget.init(); + widget.processIncomingData({value: null}); - expect(document.getElementById('message').textContent).toBe("--ºC"); + expect(shadowDOM.getElementById('message').textContent).toBe("--ºC"); }); }); @@ -201,33 +220,33 @@ describe("unit override", () => { it("number", () => { - init(); - processIncomingData({value: 5, unit: "km/h"}); + widget.init(); + widget.processIncomingData({value: 5, unit: "km/h"}); - expect(document.getElementById('message').textContent).toBe("5km/h"); + expect(shadowDOM.getElementById('message').textContent).toBe("5km/h"); }); it("string", () => { MashupPlatform.prefs.set("default-unit", "ºC"); - init(); - processIncomingData({value: "new content", unit: ""}); + widget.init(); + widget.processIncomingData({value: "new content", unit: ""}); - expect(document.getElementById('message').textContent).toBe("new content"); + expect(shadowDOM.getElementById('message').textContent).toBe("new content"); }); it("boolean", () => { MashupPlatform.prefs.set("default-unit", "ºC"); - init(); - processIncomingData({value: true, unit: null}); + widget.init(); + widget.processIncomingData({value: true, unit: null}); - expect(document.getElementById('message').textContent).toBe("true"); + expect(shadowDOM.getElementById('message').textContent).toBe("true"); }); it("null", () => { - init(); - processIncomingData({value: null, unit: "km/h"}); + widget.init(); + widget.processIncomingData({value: null, unit: "km/h"}); - expect(document.getElementById('message').textContent).toBe("--km/h"); + expect(shadowDOM.getElementById('message').textContent).toBe("--km/h"); }); });