UNPKG

node-red-contrib-uibuilder

Version:

Easily create data-driven web UI's for Node-RED. Single- & Multi-page. Multiple UI's. Work with existing web development workflows or mix and match with no-code/low-code features.

10 lines (9 loc) 31.4 kB
var D=Object.create;var $=Object.defineProperty;var I=Object.getOwnPropertyDescriptor;var T=Object.getOwnPropertyNames;var R=Object.getPrototypeOf,q=Object.prototype.hasOwnProperty;var P=(y,t,e)=>t in y?$(y,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):y[t]=e;var C=(y=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(y,{get:(t,e)=>(typeof require<"u"?require:t)[e]}):y)(function(y){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+y+'" is not supported')});var B=(y,t,e,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of T(t))!q.call(y,i)&&i!==e&&$(y,i,{get:()=>t[i],enumerable:!(r=I(t,i))||r.enumerable});return y};var x=(y,t,e)=>(e=y!=null?D(R(y)):{},B(t||!y||!y.__esModule?$(e,"default",{value:y,enumerable:!0}):e,y));var p=(y,t,e)=>P(y,typeof t!="symbol"?t+"":t,e);function L(y={}){let{content:t="",title:e="",icon:r="",type:i="info",showDismiss:a,autoClose:l=5,time:s=!0}=y,c="uib-info-overlay",u=document.getElementById(c);u||(u=document.createElement("div"),u.id=c,document.body.appendChild(u),console.log(">> SHOW OVERLAY >>",y,document.getElementById(c)));let o="overlay-entry-".concat(Date.now(),"-").concat(Math.random().toString(36).substr(2,9)),d=document.createElement("div");d.id=o,d.style.marginBottom="0.5rem";let f={info:{iconDefault:"\u2139\uFE0F",titleDefault:"Information",color:"hsl(188.2deg 77.78% 40.59%)"},success:{iconDefault:"\u2705",titleDefault:"Success",color:"hsl(133.7deg 61.35% 40.59%)"},warning:{iconDefault:"\u26A0\uFE0F",titleDefault:"Warning",color:"hsl(35.19deg 84.38% 62.35%)"},error:{iconDefault:"\u274C",titleDefault:"Error",color:"hsl(2.74deg 92.59% 62.94%)"}},m=f[i]||f.info,h=a!==void 0?a:l===null,g=r||m.iconDefault,b=e||m.titleDefault,v="";if(s){let w=new Date,M=w.getFullYear(),A=String(w.getMonth()+1).padStart(2,"0"),j=String(w.getDate()).padStart(2,"0"),H=String(w.getHours()).padStart(2,"0"),N=String(w.getMinutes()).padStart(2,"0"),U=String(w.getSeconds()).padStart(2,"0"),O="".concat(M,"-").concat(A,"-").concat(j," ").concat(H,":").concat(N,":").concat(U);v='<div class="uib-overlay-time" style="font-size: 0.8em; color: var(--text3, #999); margin-left: auto; margin-right: '.concat(h?"0.5rem":"0",';">').concat(O,"</div>")}d.innerHTML='\n <div class="uib-overlay-entry" style="--callout-color:'.concat(m.color,';">\n <div class="uib-overlay-header">\n <div class="uib-overlay-icon">').concat(g,'</div>\n <div class="uib-overlay-title">').concat(b,"</div>\n ").concat(v,"\n ").concat(h?'<button class="uib-overlay-dismiss" data-entry-id="'.concat(o,'" title="Close">\xD7</button>'):"",'\n </div>\n <div class="uib-overlay-content">\n ').concat(t,"\n </div>\n </div>\n "),u.children.length>0?u.insertBefore(d,u.firstChild):u.appendChild(d);let E=()=>{let w=document.getElementById(o);w&&(w.style.animation="slideOut 0.3s ease-in",setTimeout(()=>{w.parentNode&&w.remove()},300))},k=d.querySelector(".uib-overlay-dismiss");k&&k.addEventListener("click",E);let S=null;return l!==null&&l>0&&(S=setTimeout(E,l*1e3)),{close:()=>{S&&clearTimeout(S),E()},id:o}}var n,G=(n=class{constructor(t,e,r){p(this,"version","7.5.0-src");p(this,"sanitiseExtraTags",["uib-var"]);p(this,"sanitiseExtraAttribs",["variable","report","undefined"]);p(this,"ui_md_plugins");if(t)n.win=t;else throw new Error("Ui:constructor. Current environment does not include `window`, UI functions cannot be used.");n.doc=n.win.document,e?n.log=e:n.log=function(){return function(){}},r?this.syntaxHighlight=r:this.syntaxHighlight=function(){},n.win.markdownit&&(n.mdOpts={html:!0,xhtmlOut:!1,linkify:!0,_highlight:!0,_strict:!1,_view:"html",langPrefix:"language-",highlight:function(i,a){if(a&&window.hljs&&window.hljs.getLanguage(a))try{return'<pre class="">\n <code class="hljs border">'.concat(window.hljs.highlight(i,{language:a,ignoreIllegals:!0}).value,"</code></pre>")}finally{}return'<pre class="hljs border"><code>'.concat(n.md.utils.escapeHtml(i).trim(),"</code></pre>")}},n.md=n.win.markdownit(n.mdOpts))}_markDownIt(){if(n.win.markdownit&&(!this.ui_md_plugins&&n.win.uibuilder&&n.win.uibuilder.ui_md_plugins&&(this.ui_md_plugins=n.win.uibuilder.ui_md_plugins),n.mdOpts={html:!0,xhtmlOut:!1,linkify:!0,_highlight:!0,_strict:!1,_view:"html",langPrefix:"language-",highlight:function(t,e){if(window.hljs)if(e&&window.hljs.getLanguage(e))try{return'<pre><code class="hljs border language-'.concat(e,'" data-language="').concat(e,'" title="Source language: \'').concat(e,"'\">").concat(window.hljs.highlight(t,{language:e,ignoreIllegals:!0}).value,"</code></pre>")}finally{}else try{let r=window.hljs.highlightAuto(t);return'<pre><code class="hljs border language-'.concat(r.language,'" data-language="').concat(r.language,'" title="Source language estimated by HighlightJS: \'').concat(r.language,"'\">").concat(r.value,"</code></pre>")}finally{}return'<pre><code class="border">'.concat(n.md.utils.escapeHtml(t).trim(),"</code></pre>")}},n.md=n.win.markdownit(n.mdOpts),this.ui_md_plugins)){if(!Array.isArray(this.ui_md_plugins)){n.log("error","Ui:_markDownIt:plugins","Could not load plugins, ui_md_plugins is not an array")();return}this.ui_md_plugins.forEach(t=>{if(typeof t=="string")n.md.use(n.win[t]);else{let e=Object.keys(t)[0];n.md.use(n.win[e],t[e])}})}}_showNotification(t){t.topic&&!t.title&&(t.title=t.topic),t.title||(t.title="uibuilder notification"),t.payload&&!t.body&&(t.body=t.payload),t.body||(t.body=" No message given.");try{let e=new Notification(t.title,t);return new Promise((r,i)=>{e.addEventListener("close",a=>{a.currentTarget.userAction="close",r(a)}),e.addEventListener("click",a=>{a.currentTarget.userAction="click",r(a)}),e.addEventListener("error",a=>{a.currentTarget.userAction="error",i(a)})})}catch{return Promise.reject(new Error("Browser refused to create a Notification"))}}_uiAdd(t,e){n.log("trace","Ui:_uiManager:add","Starting _uiAdd")(),t.components.forEach((r,i)=>{n.log("trace","Ui:_uiAdd:components-forEach:".concat(i),"Component to add: ",r)();let a;switch(r.type){case"html":{r.ns="html",a=n.doc.createElement("div");break}case"svg":{r.ns="svg",a=n.doc.createElementNS("http://www.w3.org/2000/svg","svg");break}default:{r.ns="dom",a=n.doc.createElement(r.type);break}}!r.slot&&t.payload&&(r.slot=t.payload),this._uiComposeComponent(a,r);let l;r.parentEl?l=r.parentEl:t.parentEl?l=t.parentEl:r.parent?l=n.doc.querySelector(r.parent):t.parent&&(l=n.doc.querySelector(t.parent)),l||(n.log("info","Ui:_uiAdd","No parent found, adding to body")(),l=n.doc.querySelector("body")),r.position&&r.position==="first"?l.insertBefore(a,l.firstChild):r.position&&Number.isInteger(Number(r.position))?l.insertBefore(a,l.children[r.position]):l.appendChild(a),r.components&&this._uiExtendEl(a,r.components,r.ns)})}_uiComposeComponent(t,e){e.attributes&&Object.keys(e.attributes).forEach(r=>{r==="class"&&Array.isArray(e.attributes[r])&&e.attributes[r].join(" "),n.log("trace","_uiComposeComponent:attributes-forEach","Attribute: '".concat(r,"', value: '").concat(e.attributes[r],"'"))(),r==="value"&&(t.value=e.attributes[r]),r.startsWith("xlink:")?t.setAttributeNS("http://www.w3.org/1999/xlink",r,e.attributes[r]):t.setAttribute(r,e.attributes[r])}),e.id&&t.setAttribute("id",e.id),e.type==="svg"&&(t.setAttributeNS("http://www.w3.org/2000/xmlns/","xmlns","http://www.w3.org/2000/svg"),t.setAttributeNS("http://www.w3.org/2000/xmlns/","xmlns:xlink","http://www.w3.org/1999/xlink")),e.events&&Object.keys(e.events).forEach(r=>{r.toLowerCase==="onclick"&&(r="click");try{t.addEventListener(r,i=>{new Function("evt","".concat(e.events[r],"(evt)"))(i)})}catch(i){n.log("error","Ui:_uiComposeComponent","Add event '".concat(r,"' for element '").concat(e.type,"': Cannot add event handler. ").concat(i.message))()}}),e.properties&&Object.keys(e.properties).forEach(r=>{t[r]=e.properties[r],["value","checked"].includes(r)&&(t.dispatchEvent(new Event("input")),t.dispatchEvent(new Event("change")))}),e.slot&&this.replaceSlot(t,e.slot),e.slotMarkdown&&this.replaceSlotMarkdown(t,e)}_uiExtendEl(t,e,r=""){e.forEach((i,a)=>{n.log("trace","Ui:_uiExtendEl:components-forEach:".concat(a),i)();let l;i.ns=r,i.ns==="html"?(l=t,this.replaceSlot(t,i.slot)):i.ns==="svg"?(l=n.doc.createElementNS("http://www.w3.org/2000/svg",i.type),this._uiComposeComponent(l,i),t.appendChild(l)):(l=n.doc.createElement(i.type==="html"?"div":i.type),this._uiComposeComponent(l,i),t.appendChild(l)),i.components&&this._uiExtendEl(l,i.components,i.ns)})}_uiLoad(t){t.components&&(Array.isArray(t.components)||(t.components=[t.components]),t.components.forEach(async e=>{Promise.resolve().then(()=>x(C(e)))})),t.srcScripts&&(Array.isArray(t.srcScripts)||(t.srcScripts=[t.srcScripts]),t.srcScripts.forEach(e=>{this.loadScriptSrc(e)})),t.txtScripts&&(Array.isArray(t.txtScripts)||(t.txtScripts=[t.txtScripts]),this.loadScriptTxt(t.txtScripts.join("\n"))),t.srcStyles&&(Array.isArray(t.srcStyles)||(t.srcStyles=[t.srcStyles]),t.srcStyles.forEach(e=>{this.loadStyleSrc(e)})),t.txtStyles&&(Array.isArray(t.txtStyles)||(t.txtStyles=[t.txtStyles]),this.loadStyleTxt(t.txtStyles.join("\n")))}_uiManager(t){t._ui&&(Array.isArray(t._ui)||(t._ui=[t._ui]),t._ui.forEach((e,r)=>{if(e.mode&&!e.method&&(e.method=e.mode),!e.method){n.log("error","Ui:_uiManager","No method defined for msg._ui[".concat(r,"]. Ignoring. "),e)();return}switch(e.payload=t.payload,e.topic=t.topic,e.method){case"add":{this._uiAdd(e,!1);break}case"remove":{this._uiRemove(e,!1);break}case"removeAll":{this._uiRemove(e,!0);break}case"replace":{this._uiReplace(e);break}case"update":{this._uiUpdate(e);break}case"load":{this._uiLoad(e);break}case"reload":{this._uiReload();break}case"notify":{this.showDialog("notify",e,t);break}case"alert":{this.showDialog("alert",e,t);break}default:{n.log("error","Ui:_uiManager","Invalid msg._ui[".concat(r,"].method (").concat(e.method,"). Ignoring"))();break}}}))}_uiReload(){n.log("trace","Ui:uiManager:reload","reloading")(),location.reload()}_uiRemove(t,e=!1){t.components.forEach(r=>{let i;e!==!0?i=[n.doc.querySelector(r)]:i=n.doc.querySelectorAll(r),i.forEach(a=>{try{a.remove()}catch(l){n.log("trace","Ui:_uiRemove","Could not remove. ".concat(l.message))()}})})}_uiReplace(t){n.log("trace","Ui:_uiReplace","Starting")(),t.components.forEach((e,r)=>{n.log("trace","Ui:_uiReplace:components-forEach:".concat(r),"Component to replace: ",e)();let i;if(e.id?i=n.doc.getElementById(e.id):e.selector||e.select?i=n.doc.querySelector(e.selector):e.name?i=n.doc.querySelector('[name="'.concat(e.name,'"]')):e.type&&(i=n.doc.querySelector(e.type)),n.log("trace","Ui:_uiReplace:components-forEach:".concat(r),"Element to replace: ",i)(),i==null){n.log("trace","Ui:_uiReplace:components-forEach:".concat(r,":noReplace"),"Cannot find the DOM element. Adding instead.",e)(),this._uiAdd({components:[e]},!1);return}let a;switch(e.type){case"html":{e.ns="html",a=n.doc.createElement("div");break}case"svg":{e.ns="svg",a=n.doc.createElementNS("http://www.w3.org/2000/svg","svg");break}default:{e.ns="dom",a=n.doc.createElement(e.type);break}}this._uiComposeComponent(a,e),i.replaceWith(a),e.components&&this._uiExtendEl(a,e.components,e.ns)})}_uiUpdate(t){n.log("trace","UI:_uiUpdate:update","Starting _uiUpdate",t)(),t.components||(t.components=[Object.assign({},t)]),t.components.forEach((e,r)=>{n.log("trace","_uiUpdate:components-forEach","Start loop #".concat(r),e)();let i;if(e.parentEl?i=e.parentEl:e.id?i=n.doc.querySelectorAll("#".concat(e.id)):e.selector||e.select?i=n.doc.querySelectorAll(e.selector):e.name?i=n.doc.querySelectorAll('[name="'.concat(e.name,'"]')):e.type&&(i=n.doc.querySelectorAll(e.type)),i===void 0||i.length<1){n.log("warn","Ui:_uiManager:update","Cannot find the DOM element. Ignoring.",e)();return}n.log("trace","_uiUpdate:components-forEach","Element(s) to update. Count: ".concat(i.length),i)(),!e.slot&&e.payload&&(e.slot=e.payload),i.forEach((a,l)=>{if(n.log("trace","_uiUpdate:components-forEach","Updating element #".concat(l),a)(),this._uiComposeComponent(a,e),e.components){n.log("trace","_uiUpdate:nested-component","Element #".concat(l," - nested-component"),e,a)();let s={_ui:[]};e.components.forEach((c,u)=>{let o=c.method||e.method||t.method;c.method&&delete c.method,Array.isArray(c)||(c=[c]),n.log("trace","_uiUpdate:nested-component","Element #".concat(l," - nested-component #").concat(u),c)(),s._ui.push({method:o,parentEl:a,components:c})}),n.log("trace","_uiUpdate:nested-component","Element #".concat(l," - nested-component new manager"),s)(),this._uiManager(s)}})})}$(t,e,r){if(r||(r=n.doc),e||(e="el"),!r||!r.nodeType)return n.log(1,"Uib:$","Invalid context element. Must be a valid HTML element.",r)(),null;let i=r.querySelector(t);if(!i||!i.nodeType)return n.log(1,"Uib:$","No element found or element is not an HTML element for CSS selector ".concat(t))(),null;if(i.nodeName==="TEMPLATE"&&(i=i.content.firstElementChild,!i))return n.log(0,"Uib:$","Template selected for CSS selector ".concat(t," but it is empty"))(),null;let a;try{switch(e.toLowerCase()){case"text":{a=i.innerText;break}case"html":{a=i.innerHTML;break}case"attr":case"attributes":{a={};for(let l of i.attributes)a[l.name]=l.value;break}default:{a=i;break}}}catch(l){a=i,n.log(1,"Uib:$",'Could not process output type "'.concat(e,'" for CSS selector ').concat(t,", returned the DOM element. ").concat(l.message),l)()}return a}$$(t,e){return e||(e=n.doc),!e||!e.nodeType?(n.log(1,"Uib:$$","Invalid context element. Must be a valid HTML element.",e)(),null):Array.from(e.querySelectorAll(t))}addClass(t,e){Array.isArray(t)||(t=[t]),e&&e.classList.add(...t)}applyTemplate(t,e,r){var c;r||(r={}),r.onceOnly||(r.onceOnly=!1),r.mode||(r.mode="insert");let i=n.doc.getElementById(t);if(!i||i.tagName!=="TEMPLATE"){n.log("error","Ui:applyTemplate","Source must be a <template>. id='".concat(t,"'"))();return}let a=n.doc.getElementById(e);if(!a){n.log("error","Ui:applyTemplate","Target not found: id='".concat(e,"'"))();return}let l=(c=a.innerHTML)!=null?c:"";l&&r.mode==="replace"&&n.log("warn","Ui:applyTemplate","Target element is not empty, content is replaced. id='".concat(e,"'"))();let s;if(r.onceOnly===!0?s=n.doc.adoptNode(i.content):s=n.doc.importNode(i.content,!0),s){if(r.attributes){let u=s.firstElementChild;Object.keys(r.attributes).forEach(o=>{u.setAttribute(o,r.attributes[o])})}if(r.mode==="insert")a.appendChild(s);else if(r.mode==="replace")a.innerHTML="",a.appendChild(s);else if(r.mode==="wrap"&&(a.innerHTML="",a.appendChild(s),l)){let u=a.getElementsByTagName("slot");u.length>0&&(u[0].innerHTML=l)}}else n.log("warn","Ui:applyTemplate","No valid content found in template")()}convertMarkdown(t){if(!t)return"";if(!n.win.markdownit)return t;n.md||this._markDownIt();try{return n.md.render(t.trim())}catch(e){return n.log(0,"uibuilder:convertMarkdown","Could not render Markdown. ".concat(e.message),e)(),'<p class="border error">Could not render Markdown<p>'}}async include(t,e){if(!fetch)return n.log(0,"Ui:include","Current environment does not include `fetch`, skipping.")(),"Current environment does not include `fetch`, skipping.";if(!t)return n.log(0,"Ui:include","url parameter must be provided, skipping.")(),"url parameter must be provided, skipping.";if(!e||!e.id)return n.log(0,"Ui:include","uiOptions parameter MUST be provided and must contain at least an `id` property, skipping.")(),"uiOptions parameter MUST be provided and must contain at least an `id` property, skipping.";let r;try{r=await fetch(t)}catch(u){return n.log(0,"Ui:include","Fetch of file '".concat(t,"' failed. "),u.message)(),u.message}if(!r.ok)return n.log(0,"Ui:include","Fetch of file '".concat(t,"' failed. Status='").concat(r.statusText,"'"))(),r.statusText;let i=await r.headers.get("content-type"),a=null;i&&(i.includes("text/html")?a="html":i.includes("application/json")?a="json":i.includes("multipart/form-data")?a="form":i.includes("image/")?a="image":i.includes("video/")?a="video":i.includes("application/pdf")?a="pdf":i.includes("text/plain")&&(a="text"));let l="",s="Include successful",c;switch(a){case"html":{c=await r.text(),l=c;break}case"json":{c=await r.json(),l='<pre class="syntax-highlight">',l+=this.syntaxHighlight(c),l+="</pre>";break}case"form":{c=await r.formData(),l='<pre class="syntax-highlight">',l+=this.syntaxHighlight(c),l+="</pre>";break}case"image":{c=await r.blob(),l='<img src="'.concat(URL.createObjectURL(c),'">'),n.win.DOMPurify&&(s="Include successful. BUT DOMPurify loaded which may block its use.",n.log("warn","Ui:include:image",s)());break}case"video":{c=await r.blob(),l='<video controls autoplay><source src="'.concat(URL.createObjectURL(c),'"></video>'),n.win.DOMPurify&&(s="Include successful. BUT DOMPurify loaded which may block its use.",n.log("warn","Ui:include:video",s)());break}case"pdf":case"text":default:{c=await r.blob(),l='<iframe style="resize:both;width:inherit;height:inherit;" src="'.concat(URL.createObjectURL(c),'">'),n.win.DOMPurify&&(s="Include successful. BUT DOMPurify loaded which may block its use.",n.log("warn","Ui:include:".concat(a),s)());break}}return e.type="div",e.slot=l,e.parent||(e.parent="body"),e.attributes||(e.attributes={class:"included"}),this._uiReplace({components:[e]}),n.log("trace","Ui:include:".concat(a),s)(),s}loadScriptSrc(t){let e=n.doc.createElement("script");e.src=t,e.async=!1,n.doc.head.appendChild(e)}loadScriptTxt(t){let e=n.doc.createElement("script");e.async=!1,e.textContent=t,n.doc.head.appendChild(e)}loadStyleSrc(t){let e=n.doc.createElement("link");e.href=t,e.rel="stylesheet",e.type="text/css",n.doc.head.appendChild(e)}loadStyleTxt(t){let e=n.doc.createElement("style");e.textContent=t,n.doc.head.appendChild(e)}loadui(t){if(!fetch){n.log(0,"Ui:loadui","Current environment does not include `fetch`, skipping.")();return}if(!t){n.log(0,"Ui:loadui","url parameter must be provided, skipping.")();return}fetch(t).then(e=>{if(e.ok===!1)throw new Error("Could not load '".concat(t,"'. Status ").concat(e.status,", Error: ").concat(e.statusText));n.log("trace","Ui:loadui:then1","Loaded '".concat(t,"'. Status ").concat(e.status,", ").concat(e.statusText))();let r=e.headers.get("content-type");if(!r||!r.includes("application/json"))throw new TypeError("Fetch '".concat(t,"' did not return JSON, ignoring"));return e.json()}).then(e=>e!==void 0?(n.log("trace","Ui:loadui:then2","Parsed JSON successfully obtained")(),this._uiManager({_ui:e}),!0):!1).catch(e=>{n.log("warn","Ui:loadui:catch","Error. ",e)()})}moveElement(t){let{sourceSelector:e,targetSelector:r,moveType:i,position:a}=t;if(!document.querySelector(e)){n.log(0,"Ui:moveElement","Source element not found")();return}if(!document.querySelector(r)){n.log(0,"Ui:moveElement","Target element not found")();return}}nodeGet(t,e){let r={id:t.id===""?void 0:t.id,name:t.name,children:t.childNodes.length,type:t.nodeName,attributes:void 0,isUserInput:!!t.validity,userInput:t.validity?{value:t.value,validity:void 0,willValidate:t.willValidate,valueAsDate:t.valueAsDate,valueAsNumber:t.valueAsNumber,type:t.type}:void 0};if(["UL","OL"].includes(t.nodeName)){let i=n.doc.querySelectorAll("".concat(e," li"));i&&(r.list={entries:i.length})}if(t.nodeName==="DL"){let i=n.doc.querySelectorAll("".concat(e," dt"));i&&(r.list={entries:i.length})}if(t.nodeName==="TABLE"){let i=n.doc.querySelectorAll("".concat(e," > tbody > tr")),a=n.doc.querySelectorAll("".concat(e," > thead > tr")),l=n.doc.querySelectorAll("".concat(e," > tbody > tr:last-child > *"));(i||a||l)&&(r.table={headRows:a?a.length:0,bodyRows:i?i.length:0,columns:l?l.length:0})}if(t.nodeName!=="#text"&&t.attributes&&t.attributes.length>0){r.attributes={};for(let i of t.attributes)i.name!=="id"&&(r.attributes[i.name]=t.attributes[i.name].value),i.name==="class"&&(r.classes=Array.from(t.classList))}t.nodeName==="#text"&&(r.text=t.textContent),t.validity&&(r.userInput.validity={});for(let i in t.validity)r.userInput.validity[i]=t.validity[i];return r}async notification(t){if(typeof t=="string"&&(t={body:t}),typeof Notification>"u")return Promise.reject(new Error("Notifications not available in this browser"));let e=Notification.permission;return e==="denied"?Promise.reject(new Error("Notifications not permitted by user")):e==="granted"?this._showNotification(t):(e=await Notification.requestPermission(),e==="granted"?this._showNotification(t):Promise.reject(new Error("Notifications not permitted by user")))}removeClass(t,e){if(!t){e.removeAttribute("class");return}Array.isArray(t)||(t=[t]),e&&e.classList.remove(...t)}replaceSlot(t,e){if(!t)return;if(e||(e=""),e=this.sanitiseHTML(e),t.nodeName==="TEMPLATE"){t.innerHTML=e;return}let r=n.doc.createRange().createContextualFragment(e),i=n.doc.createRange();i.selectNodeContents(t),i.deleteContents(),t.append(r)}replaceSlotMarkdown(t,e){t&&e.slotMarkdown&&(e.slotMarkdown=this.convertMarkdown(e.slotMarkdown),e.slotMarkdown=this.sanitiseHTML(e.slotMarkdown),t.innerHTML=e.slotMarkdown)}sanitiseHTML(t){return n.win.DOMPurify?n.win.DOMPurify.sanitize(t,{ADD_TAGS:this.sanitiseExtraTags,ADD_ATTR:this.sanitiseExtraAttribs}):t}showDialog(t,e,r){(!t||!["notify","alert"].includes(t))&&(t="notify"),e||(e={noAutohide:!0,modal:!0,appendToast:!1});let i="";if(r.payload&&typeof r.payload=="string"&&(i+="<div>".concat(r.payload,"</div>")),e.content&&(i+="<div>".concat(e.content,"</div>")),i==="")return n.log(1,"Ui:showDialog","Toast content is blank. Not shown.")(),null;let a="";e.title?a=e.title:r.topic&&(a=r.topic),e.noAutohide&&(e.noAutoHide=e.noAutohide),e.noAutoHide&&(e.autohide=!e.noAutoHide),e.autoHideDelay?(e.autohide||(e.autohide=!0),e.delay=e.autoHideDelay):e.autoHideDelay=1e4,Object.prototype.hasOwnProperty.call(e,"autohide")||(e.autohide=!0);let l="",s="";t==="alert"&&(s='<svg viewBox="0 0 192.146 192.146"><path d="M108.186 144.372c0 7.054-4.729 12.32-12.037 12.32h-.254c-7.054 0-11.92-5.266-11.92-12.32 0-7.298 5.012-12.31 12.174-12.31s11.91 4.992 12.037 12.31zM88.44 125.301h15.447l2.951-61.298H85.46l2.98 61.298zm101.932 51.733c-2.237 3.664-6.214 5.921-10.493 5.921H12.282c-4.426 0-8.51-2.384-10.698-6.233a12.34 12.34 0 0 1 .147-12.349l84.111-149.22c2.208-3.722 6.204-5.96 10.522-5.96h.332c4.445.107 8.441 2.618 10.513 6.546l83.515 149.229c1.993 3.8 1.905 8.363-.352 12.066zm-10.493-6.4L96.354 21.454l-84.062 149.18h167.587z" /></svg>',e.modal=!0,e.autohide=!1),l='<div class="toast-head">'.concat(s).concat(a,'</div><div class="toast-body">').concat(i,"</div>");let c=()=>{m&&(n.doc.body.removeEventListener("keyup",o),m.removeEventListener("keyup",o),m.removeEventListener("touchend",o),m.removeEventListener("click",o),m.remove())},u=h=>{h.removeEventListener("keyup",o),h.removeEventListener("touchend",o),h.removeEventListener("click",o),h.remove(),m&&m.childElementCount===0&&c()},o=h=>{h.stopPropagation(),m&&(console.log("toasterEventHandler",h,m.contains(h.target),f.contains(h.target),f===h.target),c())},d=h=>{h.stopPropagation();let g;if(h.target.classList.contains("toast")?g=h.target:g=h.target.closest(".toast"),!g){n.log(1,"Ui:showDialog","Event target is not a (or in a) toast element, ignoring event")();return}let b=!!g.querySelector("input, textarea, button");if(console.log("toastEventHandler",b,h,g.contains(h.target),g===h.target),b){if(h.key!=="Escape")return;u(g)}u(g)},f=n.doc.createElement("div");if(f.title="Click or Esc to clear this notifcation",f.setAttribute("class","toast ".concat(t)),f.setAttribute("role",t==="alert"?"alertdialog":"dialog"),f.dataset.modal=e.modal,f.dataset.autohide=e.autohide,f.dataset.autoHideDelay=e.autoHideDelay,f.innerHTML=l,e.appendToast===!0){let h=Array.from(n.doc.body.querySelectorAll(".toast")).pop();h?h.insertAdjacentElement("afterend",f):n.doc.body.insertBefore(f,n.doc.body.firstChild)}else n.doc.body.insertBefore(f,n.doc.body.firstChild);f.addEventListener("keyup",d),f.addEventListener("click",d),f.addEventListener("touchend",d),e.autohide===!0&&setInterval(()=>{u(f)},e.autoHideDelay);let m;return e.modal===!0&&(m=n.doc.getElementById("toaster"),m===null&&(m=n.doc.createElement("div"),m.id="toaster",m.title="Click, touch, or ESC to clear notifcations",m.setAttribute("class","toaster"),m.setAttribute("arial-label","Toast message"),m.addEventListener("click",o),m.addEventListener("touchend",o),n.doc.body.addEventListener("keyup",o),n.doc.body.insertAdjacentElement("afterbegin",m))),f}showOverlay(t){return L(t)}ui(t){let e={};t._ui?e=t:e._ui=t,this._uiManager(e)}uiGet(t,e=null){let r=n.doc.querySelectorAll(t),i=[];return r.forEach(a=>{if(e){e==="classes"&&(e="class");let l=a.getAttribute(e);if(l==null)try{l=a[e]}catch{}if(l==null)e.toLowerCase()==="value"?i.push(a.innerText):i.push("Property '".concat(e,"' not found"));else{let s={},c=l.constructor.name.toLowerCase();if(c==="namednodemap")for(let u of l)s[u.name]=l[u.name].value;else if(!c.includes("map"))s[e]=l;else{let u={};for(let o in l)u[o]=l[o]}s.class&&(s.classes=Array.from(a.classList)),i.push(s)}}else i.push(this.nodeGet(a,t))}),i}uiEnhanceElement(t,e){this._uiComposeComponent(t,e)}createTable(t=[],e={parent:"body"}){if(!e.parent)throw new Error("[ui.js:createTable] opts.parent must be provided");this.buildHtmlTable(t,e)}buildHtmlTable(t,e={}){let r,i=Object.prototype.toString.apply(t);if(i==="[object Array]"||i==="[object Object]")r=Object.keys(t),t=Object.values(t);else{let o=n.doc.createElement("p");return o.textContent="Input data is not an array or an object, cannot create a table.",o}r.length>1e3&&n.log(1,"Uib:buildHtmlTable","Warning, data is ".concat(r.length," rows. Anything over 1,000 can get very slow to complete."))();let a=n.doc.createElement("table"),l=n.doc.createElement("thead"),s=n.doc.createElement("tr");if(!e.cols){if(t.length<1)throw new Error("[ui.js:buildHtmlTable] When no opts.cols is provided, data must contain at least 1 row");let o=Object.prototype.toString.apply(t[0])!=="[object Array]";s.dataset.colReference="",e.cols=[],Object.keys(t[0]).forEach((d,f)=>{e.cols.push({index:f,hasName:o,name:o?d:void 0,key:d!=null?d:f,title:d})})}a.cols=e.cols,e.cols.forEach(o=>{let d=n.doc.createElement("th");d.textContent=o.title,o.hasName===!0&&(d.dataset.colName=name),s.appendChild(d)}),l.appendChild(s),a.appendChild(l);let c=n.doc.createElement("tbody");a.appendChild(c);let u={allowHTML:!0,cols:e.cols};if(t.forEach((o,d)=>{isNaN(Number(r[d]))?u.rowId=r[d]:u.rowId=void 0,this.tblAddRow(a,o,u)}),e.parent){let o;typeof e.parent=="string"?o=n.doc.querySelector(e.parent):o=e.parent;try{o.appendChild(a)}catch(d){throw new Error("[ui.js:buildHtmlTable] Could not add table to parent. ".concat(d.message))}return}return a}tblAddRow(t,e={},r={}){let i=Object.prototype.toString.apply(t);if(Object.prototype.toString.apply(r)!=="[object Object]")throw new Error("[tblAddDataRow] options must be an object");let a=Object.prototype.toString.apply(e);if(a!=="[object Object]"&&a!=="[object Array]")throw new Error("[tblAddDataRow] rowData MUST be an object or an array containing column/cell data for each column");let l;if(i==="[object HTMLTableElement]")l=t;else if(l=n.doc.querySelector(t),!l)throw new Error('[tblAddDataRow] Table with CSS Selector "'.concat(t,'" not found'));r.body||(r.body=0),"allowHTML"in r||(r.allowHTML=!1);let s=l.getElementsByTagName("tbody")[r.body];if(!s)throw new Error("[tblAddDataRow] Table must have a tbody tag, tbody section ".concat(r.body," does not exist"));r.cols||(r.cols=this.tblGetColMeta(l));let c=r.cols,u=n.doc.createElement("tr");r.rowId&&(u.id=r.rowId);let o=[];for(let d of c){let f=n.doc.createElement("td");f.colMeta=d,d.hasName&&(f.dataset.colName=d.name),o.push(f)}if(Object.keys(e).forEach((d,f,m)=>{let h=o.find(b=>{var v;return((v=b==null?void 0:b.colMeta)==null?void 0:v.name)===d}),g;if(h)g=e[d];else{let b=Number(d);isNaN(b)&&(b=f),b<=o.length-1&&(h=o[b],g=Object.values(e)[b])}h&&(r.allowHTML?h.innerHTML=this.sanitiseHTML(g):h.textContent=g)}),u.append(...o),"afterRow"in r){let d=s.rows[r.afterRow];if(d)return d.after(u)}else if("beforeRow"in r){let d=s.rows[r.beforeRow];if(d)return d.before(u)}else if("replaceRow"in r){let d=s.rows[r.replaceRow];if(d)return d.replaceWith(u)}return s.appendChild(u)}tblAddListener(t,e={},r={}){let i=n.doc.querySelector(t);if(!i)throw new Error('Table with CSS Selector "'.concat(t,'" not found'));if(typeof r!="object")throw new Error('The "out" argument MUST be an object');e.eventScope||(e.eventScope="row"),e.returnType||(e.returnType="text"),e.eventType||(e.eventType="click"),e.pad||(e.pad=3),e.logLevel||(e.logLevel=2),"send"in e||(e.send=!0),i.querySelector("tbody").addEventListener(e.eventType,a=>{Object.keys(r).forEach(c=>delete r[c]);let l=a.target.closest("tr"),s=a.target.closest("td");if(l){r.clickType=e.eventScope,r.eventType=e.eventType;let c=r.rowIndex=l.rowIndex,u=r.cellIndex=s.cellIndex+1;if(l.id&&(r.rowId=l.id),e.eventScope==="row")l.querySelectorAll("td").forEach(o=>{let d=this.tblGetCellName(o,e.pad);r[d]=e.returnType==="text"?o.textContent.trim():o.innerHTML});else{let o=this.tblGetCellName(s,e.pad);r[o]=e.returnType==="text"?s.textContent.trim():s.innerHTML}n.log(e.logLevel,"Ui:tblAddClickListener","".concat(e.eventScope," ").concat(e.eventType," on row=").concat(c,", col=").concat(u,", data: "),r)(),e.send===!0&&n.win.uibuilder&&n.win.uibuilder.send({topic:"".concat(t," ").concat(e.eventScope," ").concat(e.eventType),payload:r})}})}tblFindColMeta(t,e,r){if(!e&&!r)throw new Error("[tblFindColMeta] Either the column metadata array or the HTML table element must be provided");!e&&r&&(e=this.tblGetColMeta(r));let i;if(e[t])i=e[t];else{let a=e.find(l=>l.name===t||l.index===Number(t));a&&(i=a)}return i}tblGetCellName(t,e=3){var r;return(r=t.getAttribute("data-col-name"))!=null?r:"C".concat(String(t.cellIndex+1).padStart(e,"0"))}tblGetColMeta(t,e={}){var l,s,c;if(e.pad||(e.pad=3),t.cols)return t.cols;let r=(l=t.querySelector("tr[data-col-reference]"))==null?void 0:l.children;if(r||(r=(s=t.querySelector("thead>tr:first-of-type"))==null?void 0:s.children),r||(r=(c=t.querySelector("tr:first-of-type"))==null?void 0:c.children),!r)return n.log(1,"Ui:tblGetColMeta","No columns found in table")(),[];let i=[],a;for(a of r){let u=!!a.dataset.colName,o=a.dataset.colName,d=a.cellIndex+1,f=u?o:"C".concat(String(a.cellIndex+1).padStart(e.pad,"0"));i.push({index:d,hasName:u,name:o,key:f,title:a.textContent})}return t.cols=i,i}tblRemoveRow(t,e,r={}){let i=Object.prototype.toString.apply(t);if(Object.prototype.toString.apply(r)!=="[object Object]")throw new Error("[tblRemoveRow] options must be an object");let a;if(i==="[object HTMLTableElement]")a=t;else if(a=n.doc.querySelector(t),!a)throw new Error('[tblRemoveRow] Table with CSS Selector "'.concat(t,'" not found'));r.body||(r.body=0);let l=a.getElementsByTagName("tbody")[r.body];if(!l)throw new Error("[tblAddDataRow] Table must have a tbody tag, tbody section ".concat(r.body," does not exist"));l.deleteRow(e)}},p(n,"win"),p(n,"doc"),p(n,"log"),p(n,"mdOpts"),p(n,"md"),n),J=G;export{J as default}; /** * @description Overlay window for displaying messages and notifications. * Included in the UI module and from there into the main uibuilder module. * @license Apache-2.0 * @author Julian Knight (Totally Information) * @copyright (c) 2025-2025 Julian Knight (Totally Information) */ //# sourceMappingURL=ui.esm.min.js.map