diff --git a/dist/js/ext/websocket.min.js.gz b/dist/js/ext/websocket.min.js.gz index 60d334f..c956f37 100644 Binary files a/dist/js/ext/websocket.min.js.gz and b/dist/js/ext/websocket.min.js.gz differ diff --git a/dist/js/secutio.js b/dist/js/secutio.js index 3805f35..72f6ded 100644 --- a/dist/js/secutio.js +++ b/dist/js/secutio.js @@ -675,7 +675,7 @@ } throw new Error(`Invalid "${properties['src-data']}" embedded source data`); } else { - return await _this.getResource(properties['src-data'].substring(1)); + return await _this.getResource(properties['src-data']); } } return {}; diff --git a/dist/js/secutio.min.js b/dist/js/secutio.min.js index e6cd869..1ed5e7e 100644 --- a/dist/js/secutio.min.js +++ b/dist/js/secutio.min.js @@ -1,2 +1,2 @@ (function(t,e){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=e()}else if(typeof define==="function"&&define.amd){define(e)}else{t.Secutio=e()}})(this,function(){"use strict";class t{constructor(t={tasks_attribute:"data-tasks",start_element:"body"}){this.triggers=new Set(["change","click","focus","init","input","keydown","mouseenter","mouseover","mouseup","mouseleave","mousemove","reset","scroll","scrollend","submit"]);this.methods=new Set(["get","post","put","patch","delete"]);this.tasksAttribute=t["tasks_attribute"];this.startElement=t["start_element"];this.tasks={};this.callbacks={};this.extensions={}}fetchOptions(t,e){let r={method:t.method,cache:"no-cache",signal:AbortSignal.timeout(1e3*(t.hasOwnProperty("timeout")?parseInt(t.timeout,10):300))};if(t.method==="post"&&Object.prototype.toString.call(e)==="[object FormData]"){r["body"]=e;return r}if(["post","put","patch"].includes(t.method)){r["headers"]={"Content-Type":"application/json"};r["body"]=JSON.stringify(e);return r}return r}async makeRequest(e,r){try{const s=await fetch(e.action,this.fetchOptions(e,r));let t={transformation:{},data:undefined,ok:s.ok,status:s.status};if(s.headers.has("Secutio-Transformation")){console.log("Secutio-Transformation:",s.headers.get("Secutio-Transformation"));const n=s.headers.get("Secutio-Transformation");if(n!==""){t.transformation=this.attrsStr2Obj(n)}}if(s.headers.has("Content-Type")){if(s.headers.get("Content-Type").includes("application/json")){const o=await s.json();t.data=o;return t}}const a=await s.text();t.data=a;return t}catch(t){return{transformation:{},data:undefined,ok:false,status:0}}}attrsStr2Obj(t){if(t===""){return{}}const e=t.replace(/[\r\n] */gm,"").replace(/\;$/,"").split(/\; */);let r={};for(const s of e){const a=s.split(/\: */);if(a.length!=2){throw new Error(`Wrong data atribute: ${s}`)}r[a[0]]=a[1]}return r}async getResource(t){if(t.length<=".json".length||!t.endsWith(".json")){throw new Error(`The ${t} file is not a valid JSON file!`)}const e=await fetch(t,{cache:"no-cache"});if(!e.ok){throw new Error(`When fetching the file ${t} \ - happen an HTTP error! status: ${e.status} ${e.statusText}`)}return await e.json()}swapContent(t,e,r){if(e===null){console.warn("no target to swap");return}if(t===null){if(r==="delete"){e.remove();return}if(r==="clean"){while(e.firstChild){e.removeChild(e.firstChild)}return}if(r==="none"){return}return}if(r==="inner"){e.replaceChildren(...t.childNodes);return}if(r==="outer"){e.replaceWith(...t.childNodes);return}if(r==="before"){e.before(...t.childNodes);return}if(r==="after"){e.after(...t.childNodes);return}if(r==="prepend"){e.prepend(...t.childNodes);return}if(r==="append"){e.append(...t.childNodes);return}throw new Error(`swap "${r}" attribute not supported`)}async runNextTask(t,e){const r=e.split(/ +/);for(const s of r){if(!this.tasks.hasOwnProperty(s)){throw new Error(`The next task "${s}" not exist in tasks file!`)}const a=this.tasks[s];if(!a.hasOwnProperty("disabled")){a["disabled"]=false}if(a.hasOwnProperty("trigger")){throw new Error(`The trigger property from "${s}" is not allowed in next task!`)}if(a.disabled===false){if(!a.hasOwnProperty("wait")){a.wait=0}setTimeout(async()=>{await this.findResourcePath(t,a);if(a.hasOwnProperty("next")){await this.runNextTask(t,a.next)}},a.wait)}}}runSubtasks(t,e){const r=e.split(/ +/);for(const s of r){if(!this.tasks.hasOwnProperty(s)){throw new Error(`The subtask "${s}" not exist in tasks file!`)}const a=this.tasks[s];if(!a.hasOwnProperty("selector")){a["traverse"]="target"}for(const o in a){if(!["traverse","selector","remove","add"].includes(o)){throw new Error(`The property "${o}" in subtask "${s}" is not allowed with property "selector"!`)}}if(Object.prototype.toString.call(a)!=="[object Object]"){throw new Error(`The properties of subtask "${s}" is not a object!`)}const n=(()=>{if(a.hasOwnProperty("traverse")){if(a.traverse==="target"){return[t]}if(a.traverse==="closest"&&a["selector"]!==""){return t.closest(a["selector"])}}if(a["selector"]!==""){return document.querySelectorAll(a["selector"])}throw new Error(`The properties of subtask "${s}" has a empty selector!`)})();if(a.hasOwnProperty("remove")&&Object.keys(a["remove"]).length===0){for(const i of n){i.remove()}continue}for(const i of n){if(a.hasOwnProperty("remove")){if(a["remove"].hasOwnProperty("attributes")){if(!Array.isArray(a["remove"]["attributes"])){throw new Error(`The property "remove/attributes" of subtask "${s}" is not an array!`)}for(const c of a["remove"]["attributes"]){if(i.hasAttribute(c)){i.removeAttribute(c);if(c==="class"||c==="style"){return true}}}}if(i.hasAttribute("class")&&a["remove"].hasOwnProperty("class")){const l=a["remove"]["class"].split(/ +/);for(const h of l){if(i.classList.contains(h)){i.classList.remove(h)}}if(i.getAttribute("class")===""){i.removeAttribute("class")}}if(i.hasAttribute("style")&&a["remove"].hasOwnProperty("style")){let t=i.style;const f=a["remove"]["style"].split(/ +/);for(const u of f){if(i.style.hasOwnProperty(u)){delete t[u]}}i.style=t;if(i.getAttribute("style")===""){i.removeAttribute("style")}}}if(a.hasOwnProperty("add")){if(a["add"].hasOwnProperty("attributes")){if(Object.prototype.toString.call(a["add"]["attributes"])!=="[object Object]"){throw new Error(`The properties "add/attributes" of subtask "${s}" is not a object!`)}for(const[c,p]of Object.entries(a["add"]["attributes"])){if(!i.hasAttribute(c)){i.setAttribute(c,p)}}}if(a["add"].hasOwnProperty("class")){const l=a["add"]["class"].split(/ +/);for(const h of l){i.classList.add(h)}}if(a["add"].hasOwnProperty("style")){if(i.hasAttribute("style")){const f=this.attrsStr2Obj(a["add"]["style"]);for(const[d,p]of Object.entries(f)){i.style[d]=p}}else{i.setAttribute("style",a["add"]["style"])}}}}}}async findElemWithTasks(t){if(t.hasChildNodes()){for(const e of t.childNodes){if(e.nodeName!=="TEMPLATE"&&e.nodeName!=="SCRIPT"&&e.nodeType!==e.TEXT_NODE&&e.nodeType!==e.COMMENT_NODE&&e.nodeType!==e.DOCUMENT_FRAGMENT_NODE){if(e.hasChildNodes()){await this.findElemWithTasks(e)}if(e.hasAttribute(this.tasksAttribute)){await this.setTask(e)}}}}}minifyJavaScript(t){return t.replace(/\/\/.*|\/\*[\s\S]*?\*\//g,"").replace(/\s+/g," ").trim()}reScript(t){for(const e of t.childNodes){if(e.hasChildNodes()){this.reScript(e)}if(e.nodeName==="SCRIPT"){const r=document.createElement("script");r.type="text/javascript";r.textContent=this.minifyJavaScript(e.textContent);e.replaceWith(r)}}}buildFragment(s){const t=document.createElement("div");try{if(!s.hasOwnProperty("template")){throw new Error(`The template not exist`)}t.insertAdjacentHTML("afterbegin",(()=>{const t=document.createElement("script");t.type="text/javascript";t.id="temporary-helper";t.innerHTML="function populateTemplate(event) {const data = event.result; return `"+s.template+"`;}";let e=0;let r=setInterval(()=>{if(e>5||document.getElementById("temporary-helper")===null){clearInterval(r);if(e>5){throw new Error(`The temporary helper already exist after 500ms!`)}}e++},100);document.body.appendChild(t);return populateTemplate(s)})());delete s.template;const e=document.getElementById("temporary-helper");if(e!==null){e.remove()}}catch(t){console.error(t)}this.reScript(t);return t}async fetchTemplate(t){try{const e=await fetch(t);if(!e.ok){throw new Error(`HTTP error! status: ${e.status} ${e.statusText}`)}return e.text()}catch(t){console.error(t)}return undefined}setTransformation(t,e){for(const[r,s]of Object.entries({target:"this",template:"",swap:"inner",after:"",before:"","is-template":false})){if(e.hasOwnProperty(r)){t[r]=e[r]}else if(s!==""&&!t.hasOwnProperty(r)){t[r]=s}}}async sequenceTasks(t,e,r){if(r.hasOwnProperty("before")&&r.before!==""){this.runSubtasks(e.currentTarget,r.before)}await this.findElemWithTasks(t);const s=r.target==="this"?e.currentTarget:document.querySelector(r.target);this.swapContent(t,s,r.hasOwnProperty("swap")?r.swap:"inner");if(r.hasOwnProperty("after")&&r.after!==""){this.runSubtasks(e.currentTarget,r.after)}}async templateManager(s,t){if(s.template.length<3){throw new Error(`Short template name "${s.template}"`)}t.template=await(async t=>{switch(Array.from(s.template)[0]){case"@":return await t.fetchTemplate(s.template.substring(1));case"#":const e=document.getElementById(s.template.substring(1));if(e===null){throw new Error(`Template "${s.template}" not exist!`)}if(e.content.hasChildNodes()&&e.content.nodeType===Node.DOCUMENT_FRAGMENT_NODE&&e.content.hasChildNodes){const r=document.createElement("textarea");r.insertAdjacentHTML("afterbegin",e.innerHTML);return r.value}throw new Error(`Invalid "${s.template}" embedded template`);default:throw new Error(`Invalid "${s.template}" selected template`)}})(this);const e=this.buildFragment(t);if(e===null){throw new Error(`An error happened while processing the "${s.template}" template`)}return e}async setTemplateData(t,r){t.result=await(async t=>{if(r.hasOwnProperty("src-data")){if(Array.from(r["src-data"])[0]==="#"){const e=document.getElementById(r["src-data"].substring(1));if(e===null){throw new Error(`Source data "${r["src-data"]}" not exist!`)}if(e.DOCUMENT_TYPE_NODE===Node.DOCUMENT_TYPE_NODE&&e.nodeName==="SCRIPT"&&e.type==="application/json"){return JSON.parse(e.textContent)}throw new Error(`Invalid "${r["src-data"]}" embedded source data`)}else{return await t.getResource(r["src-data"].substring(1))}}return{}})(this);if(r.hasOwnProperty("callback")){if(!this.callbacks.hasOwnProperty(r.callback)){throw new Error(`The registered calback "${r.callback}" not exist!`)}this.callbacks[r.callback](t)}if(r.hasOwnProperty("template")&&r.hasOwnProperty("target")&&r.target!=""){const s=await this.templateManager(r,t);await this.sequenceTasks(s,t,r)}const e=r.target==="this"?t.currentTarget:document.querySelector(r.target);if(e!==null){this.swapContent(null,e,r.hasOwnProperty("swap")?r.swap:"inner")}}async processReqData(r,t){if("template"in r){const e=this.buildFragment(r);if(e===null){throw new Error('An error happened while processing the "remote" template from server')}return e}if(!("result"in r)){throw new Error("There is no any data for the transformation")}if(typeof r.result==="object"){if(t.hasOwnProperty("template")){const e=await this.templateManager(t,r);return e}throw new Error("There is no json data for the transformation")}if(typeof r.result==="string"){if(t.hasOwnProperty("template")){const e=await this.templateManager(t,r);return e}const e=(t=>{const e=document.createElement("div");e.innerHTML=r.result;t.reScript(e);return e})(this);return e}throw new Error("There is no data for the transformation")}serialize(t){let e={};for(const[r,s]of t){if(e[r]!==undefined){if(!Array.isArray(e[r])){e[r]=[e[r]]}e[r].push(s)}else{e[r]=s}}return e}async prepareRequest(t,e){let r=undefined;if(e.hasOwnProperty("callback")){if(!this.callbacks.hasOwnProperty(e.callback)){throw new Error(`The registered callback "${e.callback}" not exist!`)}const n=this.callbacks[e.callback](t);if(n===false){if(e.hasOwnProperty("next")){delete e.next}return}r=t.data}else if(e.hasOwnProperty("trigger")&&e.trigger==="submit"){const o=t.currentTarget.closest("form");if(o!==null){const i=new FormData(o);r=e.method==="post"?i:this.serialize(i)}}const s=await this.makeRequest(e,r);console.log("Make Request Result:",s.ok,s.status);t.ok=s.ok;t.status=s.status;if(e.hasOwnProperty("error")&&!s.ok){e=this.tasks[e["error"]];if(e.hasOwnProperty("message")){s.data=e["message"]}}this.setTransformation(e,s.transformation);if(e["is-template"]==true){t.template=s.data}else{t.result=s.data}const a=await this.processReqData(t,e);await this.sequenceTasks(a,t,e)}async findResourcePath(t,e){if(e.hasOwnProperty("then")&&e.then!==""){this.runSubtasks(t.currentTarget,e.then)}if(e.hasOwnProperty("extension")){if(!e["extension"].hasOwnProperty("name")){throw new Error('The registered extension has no "name" property!')}if(this.extensions.hasOwnProperty(e["extension"]["name"])){if(!this.extensions.hasOwnProperty(e["extension"]["name"])){throw new Error(`The registered extension "${e["extension"]["name"]}" not exist!`)}this.extensions[e["extension"]["name"]](t,e);return}}if(e.hasOwnProperty("action")){if(e.action===""){throw new Error("Empty action")}if(e.hasOwnProperty("method")){e.method=e.method.toLowerCase();if(!this.methods.has(e.method)){throw new Error(`Unknown HTTP method: ${e.method}`)}}else{e["method"]="get"}await this.prepareRequest(t,e);return}await this.setTemplateData(t,e)}async processEvent(t,e){for(const r of Object.keys(e)){if(!r.startsWith("attribute-")){continue}const s=r.substring("attribute-".length);if(s.length>1&&t.currentTarget.hasAttribute(e[r])){e[s]=t.currentTarget.getAttribute(e[r])}}await this.findResourcePath(t,e);if(e.hasOwnProperty("next")&&e.next!==""){await this.runNextTask(t,e.next)}}setDefaultTrigger(t){if(t.nodeName==="FORM"){return"submit"}if(t.nodeName==="BUTTON"){return t.type==="submit"?"submit":"click"}if(t.nodeName==="INPUT"&&t.type==="button"){return"click"}return null}async setTask(t){const e=t.dataset.tasks.split(/ +/);for(const r of e){if(!this.tasks.hasOwnProperty(r)){throw new Error(`The task "${r}" not exist in tasks file!`)}const s=structuredClone(this.tasks[r]);if(s.hasOwnProperty("attribute-trigger")&&t.hasAttribute(s["attribute-trigger"])&&t.getAttribute(s["attribute-trigger"])!==""){s["trigger"]=t.getAttribute(s["attribute-trigger"])}if(!s.hasOwnProperty("disabled")){s["disabled"]=false}if(!s.hasOwnProperty("prevent")){s["prevent"]=true}if(s.trigger==="init"){if(s.disabled===false){t.addEventListener("init",async t=>{if(s.prevent){t.preventDefault()}if(s.disabled===false){try{await this.processEvent(t,s)}catch(t){console.log(`Error for "${r}": ${t}`)}}});const a=new CustomEvent("init",{bubbles:true,cancelable:true});t.dispatchEvent(a)}continue}if(s.hasOwnProperty("trigger")){if(!this.triggers.has(s.trigger)){throw new Error(`The "${s.trigger}" trigger is not allowed yet!`)}}else{s.trigger=this.setDefaultTrigger(t);if(s.trigger===null){throw new Error(`No trigger defined for "${r}"!`)}}t.addEventListener(s.trigger,async t=>{if(s.prevent){t.preventDefault()}if(s.disabled===false){try{await this.processEvent(t,s)}catch(t){console.log(`Error for "${r}": ${t}`)}}})}}async getDataTasks(){const t=document.querySelectorAll("script[data-tasktable]");for(const e of t){if(e.type.toLowerCase()!=="application/json"){throw new Error(`Wrong mime-type "${e.type}" for element tasks!`)}if(e.hasAttribute("src")&&e.src!==""){const r=await(async t=>{return await t.getResource(e.src)})(this);Object.assign(this.tasks,r);continue}const r=JSON.parse(e.text);Object.assign(this.tasks,r)}}callback_register(t,e){this.callbacks[t]=e}extension_register(t,e){this.extensions[t]=e}init(){const t=document.getElementsByTagName(this.startElement);this.getDataTasks().then(async()=>{if(Object.keys(this.tasks).length>=0){await this.findElemWithTasks(t[0])}})}}return t}); \ No newline at end of file + happen an HTTP error! status: ${e.status} ${e.statusText}`)}return await e.json()}swapContent(t,e,r){if(e===null){console.warn("no target to swap");return}if(t===null){if(r==="delete"){e.remove();return}if(r==="clean"){while(e.firstChild){e.removeChild(e.firstChild)}return}if(r==="none"){return}return}if(r==="inner"){e.replaceChildren(...t.childNodes);return}if(r==="outer"){e.replaceWith(...t.childNodes);return}if(r==="before"){e.before(...t.childNodes);return}if(r==="after"){e.after(...t.childNodes);return}if(r==="prepend"){e.prepend(...t.childNodes);return}if(r==="append"){e.append(...t.childNodes);return}throw new Error(`swap "${r}" attribute not supported`)}async runNextTask(t,e){const r=e.split(/ +/);for(const s of r){if(!this.tasks.hasOwnProperty(s)){throw new Error(`The next task "${s}" not exist in tasks file!`)}const a=this.tasks[s];if(!a.hasOwnProperty("disabled")){a["disabled"]=false}if(a.hasOwnProperty("trigger")){throw new Error(`The trigger property from "${s}" is not allowed in next task!`)}if(a.disabled===false){if(!a.hasOwnProperty("wait")){a.wait=0}setTimeout(async()=>{await this.findResourcePath(t,a);if(a.hasOwnProperty("next")){await this.runNextTask(t,a.next)}},a.wait)}}}runSubtasks(t,e){const r=e.split(/ +/);for(const s of r){if(!this.tasks.hasOwnProperty(s)){throw new Error(`The subtask "${s}" not exist in tasks file!`)}const a=this.tasks[s];if(!a.hasOwnProperty("selector")){a["traverse"]="target"}for(const o in a){if(!["traverse","selector","remove","add"].includes(o)){throw new Error(`The property "${o}" in subtask "${s}" is not allowed with property "selector"!`)}}if(Object.prototype.toString.call(a)!=="[object Object]"){throw new Error(`The properties of subtask "${s}" is not a object!`)}const n=(()=>{if(a.hasOwnProperty("traverse")){if(a.traverse==="target"){return[t]}if(a.traverse==="closest"&&a["selector"]!==""){return t.closest(a["selector"])}}if(a["selector"]!==""){return document.querySelectorAll(a["selector"])}throw new Error(`The properties of subtask "${s}" has a empty selector!`)})();if(a.hasOwnProperty("remove")&&Object.keys(a["remove"]).length===0){for(const i of n){i.remove()}continue}for(const i of n){if(a.hasOwnProperty("remove")){if(a["remove"].hasOwnProperty("attributes")){if(!Array.isArray(a["remove"]["attributes"])){throw new Error(`The property "remove/attributes" of subtask "${s}" is not an array!`)}for(const c of a["remove"]["attributes"]){if(i.hasAttribute(c)){i.removeAttribute(c);if(c==="class"||c==="style"){return true}}}}if(i.hasAttribute("class")&&a["remove"].hasOwnProperty("class")){const l=a["remove"]["class"].split(/ +/);for(const h of l){if(i.classList.contains(h)){i.classList.remove(h)}}if(i.getAttribute("class")===""){i.removeAttribute("class")}}if(i.hasAttribute("style")&&a["remove"].hasOwnProperty("style")){let t=i.style;const f=a["remove"]["style"].split(/ +/);for(const u of f){if(i.style.hasOwnProperty(u)){delete t[u]}}i.style=t;if(i.getAttribute("style")===""){i.removeAttribute("style")}}}if(a.hasOwnProperty("add")){if(a["add"].hasOwnProperty("attributes")){if(Object.prototype.toString.call(a["add"]["attributes"])!=="[object Object]"){throw new Error(`The properties "add/attributes" of subtask "${s}" is not a object!`)}for(const[c,p]of Object.entries(a["add"]["attributes"])){if(!i.hasAttribute(c)){i.setAttribute(c,p)}}}if(a["add"].hasOwnProperty("class")){const l=a["add"]["class"].split(/ +/);for(const h of l){i.classList.add(h)}}if(a["add"].hasOwnProperty("style")){if(i.hasAttribute("style")){const f=this.attrsStr2Obj(a["add"]["style"]);for(const[d,p]of Object.entries(f)){i.style[d]=p}}else{i.setAttribute("style",a["add"]["style"])}}}}}}async findElemWithTasks(t){if(t.hasChildNodes()){for(const e of t.childNodes){if(e.nodeName!=="TEMPLATE"&&e.nodeName!=="SCRIPT"&&e.nodeType!==e.TEXT_NODE&&e.nodeType!==e.COMMENT_NODE&&e.nodeType!==e.DOCUMENT_FRAGMENT_NODE){if(e.hasChildNodes()){await this.findElemWithTasks(e)}if(e.hasAttribute(this.tasksAttribute)){await this.setTask(e)}}}}}minifyJavaScript(t){return t.replace(/\/\/.*|\/\*[\s\S]*?\*\//g,"").replace(/\s+/g," ").trim()}reScript(t){for(const e of t.childNodes){if(e.hasChildNodes()){this.reScript(e)}if(e.nodeName==="SCRIPT"){const r=document.createElement("script");r.type="text/javascript";r.textContent=this.minifyJavaScript(e.textContent);e.replaceWith(r)}}}buildFragment(s){const t=document.createElement("div");try{if(!s.hasOwnProperty("template")){throw new Error(`The template not exist`)}t.insertAdjacentHTML("afterbegin",(()=>{const t=document.createElement("script");t.type="text/javascript";t.id="temporary-helper";t.innerHTML="function populateTemplate(event) {const data = event.result; return `"+s.template+"`;}";let e=0;let r=setInterval(()=>{if(e>5||document.getElementById("temporary-helper")===null){clearInterval(r);if(e>5){throw new Error(`The temporary helper already exist after 500ms!`)}}e++},100);document.body.appendChild(t);return populateTemplate(s)})());delete s.template;const e=document.getElementById("temporary-helper");if(e!==null){e.remove()}}catch(t){console.error(t)}this.reScript(t);return t}async fetchTemplate(t){try{const e=await fetch(t);if(!e.ok){throw new Error(`HTTP error! status: ${e.status} ${e.statusText}`)}return e.text()}catch(t){console.error(t)}return undefined}setTransformation(t,e){for(const[r,s]of Object.entries({target:"this",template:"",swap:"inner",after:"",before:"","is-template":false})){if(e.hasOwnProperty(r)){t[r]=e[r]}else if(s!==""&&!t.hasOwnProperty(r)){t[r]=s}}}async sequenceTasks(t,e,r){if(r.hasOwnProperty("before")&&r.before!==""){this.runSubtasks(e.currentTarget,r.before)}await this.findElemWithTasks(t);const s=r.target==="this"?e.currentTarget:document.querySelector(r.target);this.swapContent(t,s,r.hasOwnProperty("swap")?r.swap:"inner");if(r.hasOwnProperty("after")&&r.after!==""){this.runSubtasks(e.currentTarget,r.after)}}async templateManager(s,t){if(s.template.length<3){throw new Error(`Short template name "${s.template}"`)}t.template=await(async t=>{switch(Array.from(s.template)[0]){case"@":return await t.fetchTemplate(s.template.substring(1));case"#":const e=document.getElementById(s.template.substring(1));if(e===null){throw new Error(`Template "${s.template}" not exist!`)}if(e.content.hasChildNodes()&&e.content.nodeType===Node.DOCUMENT_FRAGMENT_NODE&&e.content.hasChildNodes){const r=document.createElement("textarea");r.insertAdjacentHTML("afterbegin",e.innerHTML);return r.value}throw new Error(`Invalid "${s.template}" embedded template`);default:throw new Error(`Invalid "${s.template}" selected template`)}})(this);const e=this.buildFragment(t);if(e===null){throw new Error(`An error happened while processing the "${s.template}" template`)}return e}async setTemplateData(t,r){t.result=await(async t=>{if(r.hasOwnProperty("src-data")){if(Array.from(r["src-data"])[0]==="#"){const e=document.getElementById(r["src-data"].substring(1));if(e===null){throw new Error(`Source data "${r["src-data"]}" not exist!`)}if(e.DOCUMENT_TYPE_NODE===Node.DOCUMENT_TYPE_NODE&&e.nodeName==="SCRIPT"&&e.type==="application/json"){return JSON.parse(e.textContent)}throw new Error(`Invalid "${r["src-data"]}" embedded source data`)}else{return await t.getResource(r["src-data"])}}return{}})(this);if(r.hasOwnProperty("callback")){if(!this.callbacks.hasOwnProperty(r.callback)){throw new Error(`The registered calback "${r.callback}" not exist!`)}this.callbacks[r.callback](t)}if(r.hasOwnProperty("template")&&r.hasOwnProperty("target")&&r.target!=""){const s=await this.templateManager(r,t);await this.sequenceTasks(s,t,r)}const e=r.target==="this"?t.currentTarget:document.querySelector(r.target);if(e!==null){this.swapContent(null,e,r.hasOwnProperty("swap")?r.swap:"inner")}}async processReqData(r,t){if("template"in r){const e=this.buildFragment(r);if(e===null){throw new Error('An error happened while processing the "remote" template from server')}return e}if(!("result"in r)){throw new Error("There is no any data for the transformation")}if(typeof r.result==="object"){if(t.hasOwnProperty("template")){const e=await this.templateManager(t,r);return e}throw new Error("There is no json data for the transformation")}if(typeof r.result==="string"){if(t.hasOwnProperty("template")){const e=await this.templateManager(t,r);return e}const e=(t=>{const e=document.createElement("div");e.innerHTML=r.result;t.reScript(e);return e})(this);return e}throw new Error("There is no data for the transformation")}serialize(t){let e={};for(const[r,s]of t){if(e[r]!==undefined){if(!Array.isArray(e[r])){e[r]=[e[r]]}e[r].push(s)}else{e[r]=s}}return e}async prepareRequest(t,e){let r=undefined;if(e.hasOwnProperty("callback")){if(!this.callbacks.hasOwnProperty(e.callback)){throw new Error(`The registered callback "${e.callback}" not exist!`)}const n=this.callbacks[e.callback](t);if(n===false){if(e.hasOwnProperty("next")){delete e.next}return}r=t.data}else if(e.hasOwnProperty("trigger")&&e.trigger==="submit"){const o=t.currentTarget.closest("form");if(o!==null){const i=new FormData(o);r=e.method==="post"?i:this.serialize(i)}}const s=await this.makeRequest(e,r);console.log("Make Request Result:",s.ok,s.status);t.ok=s.ok;t.status=s.status;if(e.hasOwnProperty("error")&&!s.ok){e=this.tasks[e["error"]];if(e.hasOwnProperty("message")){s.data=e["message"]}}this.setTransformation(e,s.transformation);if(e["is-template"]==true){t.template=s.data}else{t.result=s.data}const a=await this.processReqData(t,e);await this.sequenceTasks(a,t,e)}async findResourcePath(t,e){if(e.hasOwnProperty("then")&&e.then!==""){this.runSubtasks(t.currentTarget,e.then)}if(e.hasOwnProperty("extension")){if(!e["extension"].hasOwnProperty("name")){throw new Error('The registered extension has no "name" property!')}if(this.extensions.hasOwnProperty(e["extension"]["name"])){if(!this.extensions.hasOwnProperty(e["extension"]["name"])){throw new Error(`The registered extension "${e["extension"]["name"]}" not exist!`)}this.extensions[e["extension"]["name"]](t,e);return}}if(e.hasOwnProperty("action")){if(e.action===""){throw new Error("Empty action")}if(e.hasOwnProperty("method")){e.method=e.method.toLowerCase();if(!this.methods.has(e.method)){throw new Error(`Unknown HTTP method: ${e.method}`)}}else{e["method"]="get"}await this.prepareRequest(t,e);return}await this.setTemplateData(t,e)}async processEvent(t,e){for(const r of Object.keys(e)){if(!r.startsWith("attribute-")){continue}const s=r.substring("attribute-".length);if(s.length>1&&t.currentTarget.hasAttribute(e[r])){e[s]=t.currentTarget.getAttribute(e[r])}}await this.findResourcePath(t,e);if(e.hasOwnProperty("next")&&e.next!==""){await this.runNextTask(t,e.next)}}setDefaultTrigger(t){if(t.nodeName==="FORM"){return"submit"}if(t.nodeName==="BUTTON"){return t.type==="submit"?"submit":"click"}if(t.nodeName==="INPUT"&&t.type==="button"){return"click"}return null}async setTask(t){const e=t.dataset.tasks.split(/ +/);for(const r of e){if(!this.tasks.hasOwnProperty(r)){throw new Error(`The task "${r}" not exist in tasks file!`)}const s=structuredClone(this.tasks[r]);if(s.hasOwnProperty("attribute-trigger")&&t.hasAttribute(s["attribute-trigger"])&&t.getAttribute(s["attribute-trigger"])!==""){s["trigger"]=t.getAttribute(s["attribute-trigger"])}if(!s.hasOwnProperty("disabled")){s["disabled"]=false}if(!s.hasOwnProperty("prevent")){s["prevent"]=true}if(s.trigger==="init"){if(s.disabled===false){t.addEventListener("init",async t=>{if(s.prevent){t.preventDefault()}if(s.disabled===false){try{await this.processEvent(t,s)}catch(t){console.log(`Error for "${r}": ${t}`)}}});const a=new CustomEvent("init",{bubbles:true,cancelable:true});t.dispatchEvent(a)}continue}if(s.hasOwnProperty("trigger")){if(!this.triggers.has(s.trigger)){throw new Error(`The "${s.trigger}" trigger is not allowed yet!`)}}else{s.trigger=this.setDefaultTrigger(t);if(s.trigger===null){throw new Error(`No trigger defined for "${r}"!`)}}t.addEventListener(s.trigger,async t=>{if(s.prevent){t.preventDefault()}if(s.disabled===false){try{await this.processEvent(t,s)}catch(t){console.log(`Error for "${r}": ${t}`)}}})}}async getDataTasks(){const t=document.querySelectorAll("script[data-tasktable]");for(const e of t){if(e.type.toLowerCase()!=="application/json"){throw new Error(`Wrong mime-type "${e.type}" for element tasks!`)}if(e.hasAttribute("src")&&e.src!==""){const r=await(async t=>{return await t.getResource(e.src)})(this);Object.assign(this.tasks,r);continue}const r=JSON.parse(e.text);Object.assign(this.tasks,r)}}callback_register(t,e){this.callbacks[t]=e}extension_register(t,e){this.extensions[t]=e}init(){const t=document.getElementsByTagName(this.startElement);this.getDataTasks().then(async()=>{if(Object.keys(this.tasks).length>=0){await this.findElemWithTasks(t[0])}})}}return t}); \ No newline at end of file diff --git a/dist/js/secutio.min.js.gz b/dist/js/secutio.min.js.gz index aac53af..e8d56e6 100644 Binary files a/dist/js/secutio.min.js.gz and b/dist/js/secutio.min.js.gz differ diff --git a/src/js/secutio.js b/src/js/secutio.js index 3805f35..72f6ded 100644 --- a/src/js/secutio.js +++ b/src/js/secutio.js @@ -675,7 +675,7 @@ } throw new Error(`Invalid "${properties['src-data']}" embedded source data`); } else { - return await _this.getResource(properties['src-data'].substring(1)); + return await _this.getResource(properties['src-data']); } } return {};