node-red-contrib-uibuilder
Version:
Easily create web UI's for Node-RED using any (or no) front-end library. VueJS and bootstrap-vue included but change as desired.
1 lines • 17.1 kB
JavaScript
;if("undefined"!=typeof require&&"undefined"==typeof io)var io=require("socket.io-client");(function(){function a(a,b){(null===b||void 0===b)&&(b="payload"),"string"!=typeof b&&(console.warn("[uibuilderfe:makeMeAnObject] WARNING: property parameter must be a string and not: "+typeof b),b="payload");var c={};return"object"==typeof a?c=a:null!==a&&(c[b]=a),c}function b(){var a=Array.prototype.slice.call(arguments),b="/"+a.map(function(a){return a.replace(/^\/|\/$/g,"")}).filter(function(a){return a}).join("/");return b.replace("//","/")}var c=this,d=c.uibuilder,e=function(){var c=String.prototype;c.endsWith||(c.endsWith=function(a){return-1!==this.indexOf(a,this.length-a.length)});var d=this;d.version="3.3.0",d.debug=!1,d.moduleName="uibuilder",d.isUnminified=/param/.test(function(){}),d.dummyAuth={id:null,jwt:void 0,sessionExpiry:void 0,userValidated:!1,info:{error:void 0,message:void 0,validJwt:void 0}},d._auth=void 0,d.started=!1,d.uiDebug=function(){if(d.debug){var a=arguments[0];console[a].apply(console,[].slice.call(arguments,1))}},d.me=function(){return!0===d.debug?d:"uibuilderfe.js Version: "+d.version},d.uiDebug("log","\nuibuilderfe: Debug? ",d.debug,"\n\t\tVersion? ",d.version,"\n\t\tRunning Packed version? ",!d.isUnminified,"\n "),d.setIOnamespace=function(){var a="";try{a=document.cookie.match(/uibuilder-namespace\s*=.*?\s*;/g)[0].replace("uibuilder-namespace=","").replace(";","")}catch(a){}if(""===a){var b=window.location.pathname.split("/").filter(function(a){return""!==a.trim()});0<b.length&&b[b.length-1].endsWith(".html")&&b.pop(),a=b.pop(),d.uiDebug("log","uibuilderfe: IO Namespace - Found via url path: "+a)}else d.uiDebug("log","uibuilderfe: IO Namespace - Found via cookie: "+a);return a="/"+a,d.uiDebug("log","uibuilderfe: IO Namespace: "+a),a},d.autoSendReady=!0,d.allowScript=!0,d.allowStyle=!0,d.removeScript=!0,d.removeStyle=!0,d.msg={},d.ctrlMsg={},d.sentMsg={},d.sentCtrlMsg={},d.msgsSent=0,d.msgsReceived=0,d.msgsSentCtrl=0,d.msgsCtrl=0,d.ioConnected=!1,d.serverTimeOffset=null,d.isAuthorised=!1,d.authTokenExpiry=null,d.authData={},d.ioChannels={control:"uiBuilderControl",client:"uiBuilderClient",server:"uiBuilder"},d.retryMs=2e3,d.retryFactor=1.5,d.timerid=null,d.ioNamespace=d.setIOnamespace(),d.ioTransport=["polling","websocket"],d.loaded=!1,d.authToken="";var e=window.location.pathname.split("/").filter(function(a){return""!==a.trim()});return 0<e.length&&e[e.length-1].endsWith(".html")&&e.pop(),d.url=e.pop(),d.httpNodeRoot="/"+e.join("/"),d.ioPath=b(d.httpNodeRoot,d.moduleName,"vendor","socket.io"),d.uiDebug("debug","uibuilderfe: ioPath: "+d.ioPath+", httpNodeRoot: "+d.httpNodeRoot+", uibuilder url (not used): "+d.url),d.set=function(a,b){d[a]=b,d.uiDebug("debug","uibuilderfe: prop set - prop: "+a+", val: "+("object"==typeof b?JSON.stringify(b):b)),d.emit(a,b)},d.checkConnect=function(a,b){var c=c++||1;d.uiDebug("debug","uibuilderfe:checkConnect. Reconnect - Depth: "+c+", Delay: "+a+", Factor: "+b,d.ioNamespace,d.ioPath),d.timerid&&window.clearTimeout(d.timerid),d.timerid=window.setTimeout(function(){d.uiDebug("debug","uibuilderfe:checkConnect timeout. SIO reconnect attempt, timeout: "+a+", depth: "+c,d.ioNamespace,d.ioPath),console.info("[uibuilderfe:checkConnect:setTimeout] Socket.IO reconnection attempt. Current delay: "+a),d.socket.close(),d.socket.connect(),d.timerid=null,d.checkConnect(a*b,b)},a)},d.checkTimestamp=function(a){var b=Math.round;if(a.hasOwnProperty("serverTimestamp")){var c=new Date(a.serverTimestamp),e=b((new Date-c)/36e5);e!==d.serverTimeOffset&&(d.set("serverTimeOffset",e),d.uiDebug("log","uibuilderfe:"+d.ioChannels.server+" (server): Offset changed to: "+e))}},d.ioSetup=function(){d.uiDebug("debug","uibuilderfe:ioSetup: About to create IO. Namespace: "+d.ioNamespace+", Path: "+d.ioPath+", Transport: ["+d.ioTransport.join(", ")+"]"),d.socketOptions={path:d.ioPath,transports:d.ioTransport,transportOptions:{polling:{extraHeaders:{"x-clientid":"uibuilderfe"}}}},d.socket=io(d.ioNamespace,d.socketOptions),d.socket.on("connect",function(){d.uiDebug("info","uibuilderfe:ioSetup: SOCKET CONNECTED - Namespace: "+d.ioNamespace," Server Channel: ",d.ioChannels.server," Control Channel: ",d.ioChannels.control),d.set("ioConnected",!0),d.timerid&&(window.clearTimeout(d.timerid),d.timerid=null)}),d.socket.on(d.ioChannels.server,function(b){d.uiDebug("debug","uibuilderfe:ioSetup:"+d.ioChannels.server+" (server): msg received - Namespace: "+d.ioNamespace,b),b=a(b,"payload"),d.checkTimestamp(b),b._auth&&d.updateAuth(b._auth),d.allowScript&&b.hasOwnProperty("script")&&(d.newScript(b.script),d.removeScript&&delete b.script),d.allowStyle&&b.hasOwnProperty("style")&&(d.newStyle(b.style),d.removeStyle&&delete b.style),d.set("msg",b),d.set("msgsReceived",d.msgsReceived+1)}),d.socket.on(d.ioChannels.control,function(a){if(d.uiDebug("debug","uibuilder:ioSetup:"+d.ioChannels.control+" (control): msg received - Namespace: "+d.ioNamespace,a),null===a)a={};else if("object"!=typeof a){var b={};b["uibuilderCtrl:"+d.ioChannels.control]=a,a=b}switch(a.hasOwnProperty("debug")&&(d.debug=a.debug),d.checkTimestamp(a),d.set("ctrlMsg",a),d.set("msgsCtrl",d.msgsCtrl+1),a.uibuilderCtrl){case"ready for content":a._auth&&d.updateAuth(a._auth),d.uiDebug("debug","uibuilderfe:ioSetup:"+d.ioChannels.control+" Received \"ready for content\" from server");break;case"shutdown":d.uiDebug("debug","uibuilderfe:ioSetup:"+d.ioChannels.control+" Received \"shutdown\" from server"),d.set("serverShutdown",void 0);break;case"client connect":a._auth&&d.updateAuth(a._auth),!0===d.autoSendReady&&(d.uiDebug("debug","uibuilderfe:ioSetup:"+d.ioChannels.control+" Received \"client connect\" from server, auto-sending REPLAY control msg"),d.send({uibuilderCtrl:"ready for content",cacheControl:"REPLAY"},d.ioChannels.control));break;case"authorised":d.uiDebug("debug","uibuilderfe:ioSetup:"+d.ioChannels.control+" Received \"authorised\" from server"),a._auth?d.updateAuth(a._auth):(d.uiDebug("debug","uibuilderfe:ioSetup:"+d.ioChannels.control+" Received \"authorised\" from server but without a _auth property - logon failed"),d.markLoggedOut("Logon succeeded but no _auth received, logged out"));break;case"authorisation failure":d.uiDebug("debug","uibuilderfe:ioSetup:"+d.ioChannels.control+" Received \"authorisation failure\" from server"),d.markLoggedOut("Logon authorisation failure",a._auth.authData);break;case"logged off":d.uiDebug("debug","uibuilderfe:ioSetup:"+d.ioChannels.control+" Received \"logged off\" from server"),d.markLoggedOut("Logged off by logout() request",a._auth);break;default:d.uiDebug("debug","uibuilderfe:ioSetup:"+d.ioChannels.control+" Received \""+a.uibuilderCtrl+"\" from server"),a._auth&&d.updateAuth(a._auth);}}),d.socket.on("disconnect",function(a){d.uiDebug("info","uibuilderfe:ioSetup: SOCKET DISCONNECTED - Namespace: "+d.ioNamespace+", Reason: "+a),d.set("ioConnected",!1),console.warn("[uibuilderfe:socket-disconnect] Reason: "+a),d.checkConnect(d.retryMs,d.retryFactor)}),d.socket.on("connect_error",function(a){d.uiDebug("error","uibuilderfe:ioSetup: SOCKET CONNECT ERROR - Namespace: "+d.ioNamespace+" ioPath: "+d.ioPath+", Reason: "+a.message)}),d.socket.on("error",function(a){d.uiDebug("warn","uibuilderfe:ioSetup: SOCKET ERROR from server - MESSAGE: ",a),d.set("socketError",a)}),d.checkConnect(d.retryMs,d.retryFactor)},d.markLoggedOut=function(a,b){void 0===d._auth&&void 0===b||(b=d.dummyAuth,void 0!==a&&(d._auth.info.message=a),d.set("isAuthorised",!1),d.set("_auth",b))},d.logon=function(a,b){if(void 0!==d._auth||void 0!==a)return void 0===a&&(a=d._auth),void 0===a.id||null===a.id||0===a.id.length?void console.error("[uibuilder:logon] No logon id supplied, ignoring request."):void(!a.info&&(a.info=d.dummyAuth.info),d.set("_auth",a),b||d.send({uibuilderCtrl:"logon",from:"client",_auth:d._auth},d.ioChannels.control),d.uiDebug("log","[uibuilder:logon] ",d._auth))},d.logoff=function(a,b){if(void 0!==d._auth||void 0!==a)return void 0===a&&(a=d._auth),void 0===a.id||null===a.id||0===a.id.length?void console.error("[uibuilder:logoff] No logoff id supplied, ignoring request."):void(!a.info&&(a.info=d.dummyAuth.info),d._auth=a,b||d.send({uibuilderCtrl:"logoff",from:"client",_auth:d._auth},d.ioChannels.control))},d.updateAuth=function(a){if(void 0!==d._auth||void 0!==a)return void 0===a&&(a=d._auth),void 0===a.id||null===a.id||0===a.id.length?(console.error("[uibuilder:updateAuth] No auth id supplied by server, ignoring server response."),void(a.info&&a.info.error&&console.warn("[uibuilder:updateAuth] Error from Server: ",a.info.error))):void(!a.info&&(a.info=d.dummyAuth.info),a.userValidated&&a.jwt&&!0===a.info.validJwt&&new Date(a.sessionExpiry)>new Date?(d.set("isAuthorised",!0),d.set("_auth",a)):d.markLoggedOut("Logon succeeded but no token received, logged out"))},d.sendAuth=function(){try{return void 0===d._auth?void 0:d.isAuthorised?new Date(d._auth.sessionExpiry)>new Date?d._auth:(d.markLoggedOut("Automatically logged off. Token expired"),d._auth):d._auth}catch(a){}},d.send=function(b,c){(null===c||void 0===c)&&(c=d.ioChannels.client),d.uiDebug("log","uibuilderfe: sending msg - Namespace: "+d.ioNamespace+", Channel: "+c,b),c===d.ioChannels.client?b=a(b,"payload"):c===d.ioChannels.control&&(b=a(b,"uibuilderCtrl"),!b.hasOwnProperty("uibuilderCtrl")&&(b.uibuilderCtrl="manual send"),b.from="client"),b._socketId=d.socket.id,b._auth=d.sendAuth(),c===d.ioChannels.client?(d.set("sentMsg",b),d.set("msgsSent",d.msgsSent+1)):c===d.ioChannels.control&&(d.set("sentCtrlMsg",b),d.set("msgsSentCtrl",d.msgsSentCtrl+1)),d.socket.emit(c,b)},d.onChange=function(a,b){d.events[a]?d.events[a].push(b):d.events[a]=[b]},d.clearEventListeners=function(){d.events=[]},d.events={},d.emit=function(a){var b=d.events[a];if(b)for(var c=Array.prototype.slice.call(arguments,1),e=0;e<b.length;e++)b[e].apply(d,c)},d.newScript=function(a){if(!0===d.allowScript&&""!==a&&"undefined"!=typeof a){d.uiDebug("log","uibuilderfe: newCode - script: "+a);var b=document.createElement("script");b.type="text/javascript",b.defer=!0,b.textContent=a,document.getElementsByTagName("body")[0].appendChild(b)}},d.newStyle=function(a){if(!0===d.allowStyle&&""!==a&&"undefined"!=typeof a){d.uiDebug("log","uibuilderfe: newStyle - style: "+a);var b=document.createElement("style");b.textContent=a,document.getElementsByTagName("head")[0].appendChild(b)}},d.showToast=function(a){if(!d.vueApp)return void console.warn("[uibuilder:toast] Vue app object not available, cannot create a toast");if(!d.vueApp.$bvToast)return void console.warn("[uibuilder:toast] bootstrap-vue toast component not available, cannot create a toast");if(!a._uib||null===a._uib||"Object"!==a._uib.constructor.name)return void console.warn("[uibuilder:toast] Incoming msg requires msg._uib object, cannot create a toast");const b=d.vueApp.$createElement;let c={};a._uib.options&&(c=Object.assign({},a._uib.options));let e="";a.payload&&(e+=a.payload),c.content&&(e+=c.content);const f=b("p",{domProps:{innerHTML:e}});return c.title&&(c.title=b("p",{domProps:{innerHTML:c.title}})),c.append&&(c.appendToast=c.append),c.autoHideDelay&&(c.autohide=!0,c.delay=c.autoHideDelay),""===e?void console.warn("[uibuilder:toast] Toast content is blank. Not shown."):void d.vueApp.$bvToast.toast(f,c)},d.showAlert=function(){},d.showComponentDetails=function(a){if(!d.vueApp)return;if(!d.vueApp.$refs[a])return;let b=d.vueApp.$refs[a],c={};if(b.$options)c={uibuilderCtrl:"vue component details",componentDetails:{ref:a,tag:b.$options._componentTag,props:b.$options._propKeys}};else{let b=`[uibuilderfe:showComponentDetails] ref="${a}" is not a Vue Component. Details cannot be returned.`;d.uiDebug("warn",b),c={uibuilderCtrl:"vue component details",componentDetails:{warning:b,ref:a,tag:null,props:null}}}return c},d.onChange("msg",function(a){if(!d.vueApp)return;if(!a._uib)return;if(!0===a._uib.reload&&(console.log("reloading"),location.reload()),!a._uib.componentRef)return;let b=d.vueApp,c=a._uib.componentRef;if(a._uib.requestDetails){let b=d.showComponentDetails(c);return void(b&&(a.topic&&(b.topic=a.topic),d.send(b,d.ioChannels.control)))}if("globalNotification"===c)return void d.showToast(a);if("globalAlert"===c)return void d.showAlert(a);if(!(c in b.$refs)){let b=`[uibuilderfe:internal:onChange] ref="${c}" is not a Vue Component. Cannot set props.`;d.uiDebug("warn",b);let e={uibuilderCtrl:"vue component details",componentDetails:{warning:b,ref:c,tag:null,props:null}};a.topic&&(e.topic=a.topic),d.send(e,d.ioChannels.control)}else if(a._uib.options&&(d.uiDebug("log","\uD83D\uDD22\uD83D\uDCC8 new component instance options received for ref",c,":",a._uib.options),Object.keys(a._uib.options).forEach(function(f){try{b.$set(b.$refs[c],f,a._uib.options[f])}catch(a){d.uiDebug("warn",`[uibuilderfe:internal:onChange] Could not update prop "${f}" for component ref="${c}". Error: ${a.message}`)}})),a.payload){d.uiDebug("log","\uD83D\uDD22\uD83D\uDCC8 new component instance value received for ref",c,":",a.payload);try{b.$refs[c].$props.config.value=a.payload}catch(a){}}}),d.uiReturn={set:function(a,b){if(-1!==["autoSendReady","ctrlMsg","debug","events","httpNodeRoot","ioChannels","ioConnected","ioNamespace","ioPath","ioTransport","isAuthorised","isUnminified","loaded","msg","msgsCtrl","msgsReceived","msgsSent","msgsSentCtrl","moduleName","retryFactor","retryMs","sentMsg","sentCtrlMsg","serverTimeOffset","socket","timerid","url","version","checkConnect","checkTimestamp","emit","get","ioSetup","logon","logoff","markLoggedOut","me","newScript","newStyle","onChange","self","set","send","sendAuth","sendCtrl","setIOnamespace","showComponentDetails","showToast","socket","uiDebug","updateAuth","uiReturn"].indexOf(a))return console.warn("[uibuilder:set] Cannot use set() on protected property \""+a+"\""),void d.uiDebug("warn","uibuilderfe:uibuilder:set: \""+a+"\" is in list of excluded properties, not set");if("_auth"===a){if(!b.id||0===b.id.length)return void console.warn("[uibuilder:set] _auth must contain a valid _auth.id property");b.info||(b.info=d.dummyAuth.info)}d.set(a,b)},get:function(a){return-1===["checkConnect","checkTimestamp","emit","get","ioSetup","logon","logoff","markLoggedOut","me","newScript","newStyle","onChange","self","set","send","sendAuth","sendCtrl","setIOnamespace","showComponentDetails","showToast","socket","uiDebug","updateAuth","uiReturn"].indexOf(a)?(void 0===d[a]&&console.warn("[uibuilder] get() - property \""+a+"\" does not exist"),d[a]):(console.warn("[uibuilder] Cannot use get() on protected property \""+a+"\""),void d.uiDebug("warn","uibuilderfe:uibuilder:get: \""+a+"\" is in list of excluded properties, not get"))},onChange:d.onChange,clearEventListeners:d.clearEventListeners,msg:d.msg,send:d.send,sendCtrl:function(a){d.send(a,d.ioChannels.control)},autoSendReady:function(a){!0!==a&&(a=!1),d.autoSendReady=a},debug:function(a){return"undefined"==typeof a?d.debug:void("boolean"==typeof a&&(d.debug=a))},uiDebug:d.uiDebug,me:d.me,start:function(a,b,c){return!0===d.started?void d.uiDebug("log","\u274C [uibuilderfe:start] Start function already called. Do not call more than once."):void(d.uiDebug("log","[uibuilderfe:start] start() called"),"[object Object]"===toString.call(a)?(d.uiDebug("log","\u2705 [uibuilderfe:start] namespace IS an object!"),!0===a._isVue?(d.uiDebug("log","\u2705 [uibuilderfe:start] Vue instance object IS available!"),c=a,a=void 0):(a.ioPath&&(b=a.ioPath),a.vueApp&&(c=a.vueApp),a=a.namespace?a.namespace:void 0)):c?"[object Object]"===toString.call(c)&&!0===c._isVue?d.uiDebug("log","\u2705 [uibuilderfe:start] Vue instance object IS available!"):(d.uiDebug("log","\u274C [uibuilderfe:start] Vue instance object not available!"),c=void 0):d.uiDebug("log","\u274C [uibuilderfe:start] app1 not available!"),d.uiDebug("log","[uibuilderfe:start] Calling params - namespace",a,"ioPath",b,"vueApp",c),void 0!==a&&null!==a&&(d.ioNamespace=a),void 0!==b&&null!==b&&(d.ioPath=b),void 0!==c&&null!==c&&(d.vueApp=c),d.uiDebug("log","[uibuilderfe:start] Final Socket.IO params - namespace",a,"ioPath",b),d.ioSetup(),d.started=!0)},logon:d.logon,logoff:d.logoff,showComponentDetails:d.showComponentDetails,showToast:function(a,b="globalNotification",c={}){d.showToast({_uib:{componentRef:b,options:c},payload:a})},eventSend:function(a){if(!a.constructor.name.endsWith("Event")||!a.currentTarget)return void d.uiDebug("log","[uibuilderfe:eventSend] ARGUMENT NOT A DOM EVENT - use data attributes not function arguments to pass data");const b=a.currentTarget;let c="";try{""!==b.textContent&&(c=b.textContent.substring(0,25))}catch(a){}try{""!==b.name&&(c=b.name)}catch(a){}try{""!==b.id&&(c=b.id)}catch(a){}d.send({topic:d.msg.topic,uibDomEvent:{sourceId:c,event:a.type},payload:b.dataset})},automap:d.automap},window.addEventListener("load",function(){d.uiDebug("debug","uibuilderfe:load: All resources loaded"),d.loaded=!0}),d.uiReturn}.call(c);e.noConflict=function(){return c.uibuilder=d,e},"undefined"==typeof exports?c.uibuilder=e:("undefined"!=typeof module&&module.exports&&(exports=module.exports=e),exports.uibuilder=e)}).call(this);