If you saw my previous post, you know I've been learning about web components and js modules. If you use uibuilder, you will also know that I'm fond of including a msg display on the page that shows a formatted version of the message incoming from Node-RED.
So I thought it would be a great idea to combine things and here it is
The web component given below needs no external dependencies and should be able to work with Dashboard and other UI tooling with minimal effort. Here I'm showing it used with the blank template in uibuilder. It shows that you need just 3 lines of code! You don't just have to use it for showing Node-RED msg's of course, you can use it to show any javascript object.
I am intending to introduce a mechanism into the next release of uibuilder that will facilitate the use of these types of components (you can already use the common
folder). I will also add some simple components as standard. Watch out for more components to come, I may be on a roll!
index.html
Add this line:
<syntax-highlight>Latest msg from Node-RED:</syntax-highlight>
index.js
const {dumpObject} = await import('./syntax-highlight.js')
uibuilder.start()
uibuilder.onChange('msg', function (msg) {
dumpObject(msg)
})
syntax-highlight.js
Create this file in the same folder as your index.html file. You can use the uibuilder editor or a code editor according to your preference.
/** Web component to show a JavaScript object as a highlighted box in the UI
* @example HTML:
* <syntax-highlight>Latest msg from Node-RED:</syntax-highlight>
* @example JavaScript:
* const {dumpObject} = await import('./components/syntax-highlight.js')
* dumpObject(msg)
* @example Alternative JavaScript:
* await import('./components/syntax-highlight.js')
* document.getElementsByTagName('syntax-highlight')[0].json = msg
*/
const template = document.createElement('template')
template.innerHTML = `
<style>
:host {
display: block;
color:white;
background-color:black;
margin-top: 0.5rem;
margin-bottom: 0.5rem;
padding: 0.5rem;
}
pre {
font-family: Consolas, "ui-monospace", "Lucida Console", monospace;
white-space: pre;
margin: 0;
}
.key {color:#ffbf35}
.string {color:#5dff39;}
.number {color:#70aeff;}
.boolean {color:#b993ff;}
.null {color:#93ffe4;}
.undefined {color:#ff93c9;}
</style>
<slot></slot>
<pre><i>No data</i></pre>
`
// return formatted HTML version of JSON object
const syntaxHighlight = function (json) {
json = JSON.stringify(json, undefined, 4)
json = json.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>')
json = json.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g, function (match) {
var cls = 'number'
if ((/^"/).test(match)) {
if ((/:$/).test(match)) {
cls = 'key'
} else {
cls = 'string'
}
} else if ((/true|false/).test(match)) {
cls = 'boolean'
} else if ((/null/).test(match)) {
cls = 'null'
}
return '<span class="' + cls + '">' + match + '</span>'
})
const myHtml = document.createElement('pre')
myHtml.innerHTML = json
return myHtml
} // --- End of syntaxHighlight --- //
export class SyntaxHighlight extends HTMLElement {
constructor() {
super()
this.attachShadow({ mode: 'open', delegatesFocus: true })
.appendChild(template.content.cloneNode(true))
}
set json(value) {
//console.log(value, syntaxHighlight(value))
this.shadowRoot.removeChild(this.shadowRoot.lastElementChild)
this.shadowRoot.appendChild(syntaxHighlight(value))
}
} // ---- End of SyntaxHighlight class definition ---- //
// Add the class as a new Custom Element to the window object
customElements.define('syntax-highlight', SyntaxHighlight)
/** Quick and dirty method to dump a JavaScript object to the ui
* Will put the output to the first <syntax-highlight> tag on the page
* @param {*} obj Object to dump
* @param {number} [ref] Optional, default=0. Which tag to use? If >1 <syntax-highlight> tag is on the page.
*/
export let dumpObject = function showJson(obj, ref=0){
try {
const showMsg = document.getElementsByTagName('syntax-highlight')[ref]
showMsg.json = obj
} catch (e) {
console.error('[syntax-highlight:dumpObject] Cannot show object - is there a <syntax-highlight> tag?')
}
}