From b7700bb92af17398a87a8a5bf6955b7ced5f0c4d Mon Sep 17 00:00:00 2001 From: aanthonymax Date: Wed, 4 Dec 2024 22:13:24 +0300 Subject: [PATCH] update site --- dist/hmpl.js | 140 +- dist/hmpl.min.js | 2 +- dist/hmpl.runtime.js | 2391 ++++++++--------- .../docs/.vuepress/public/images/logo_new.svg | 16 + www/app/docs/.vuepress/styles/palette.scss | 3 +- www/app/docs/README.md | 29 +- www/app/docs/changelog.md | 7 + www/app/docs/installation.md | 41 +- www/app/docs/introduction.md | 5 +- www/app/docs/request.md | 4 +- 10 files changed, 1386 insertions(+), 1252 deletions(-) create mode 100644 www/app/docs/.vuepress/public/images/logo_new.svg diff --git a/dist/hmpl.js b/dist/hmpl.js index 3745c7e..31bdb6b 100644 --- a/dist/hmpl.js +++ b/dist/hmpl.js @@ -12,18 +12,41 @@ })(typeof self !== "undefined" ? self : this, function () { return (function () { "use strict"; + /** + * Checks if the provided value is an object (excluding arrays and null). + * @param val - The value to check. + * @returns True if val is an object, false otherwise. + */ const checkObject = (val) => { return typeof val === "object" && !Array.isArray(val) && val !== null; }; + /** + * Checks if the provided value is a function. + * @param val - The value to check. + * @returns True if val is a function, false otherwise. + */ const checkFunction = (val) => { return Object.prototype.toString.call(val) === "[object Function]"; }; + /** + * Throws a new error with the provided message. + * @param text - The error message. + */ const createError = (text) => { throw new Error(text); }; + /** + * Logs a warning message to the console. + * @param text - The warning message. + */ const createWarning = (text) => { console.warn(text); }; + /** + * Validates the HTTP method. + * @param method - The HTTP method to validate. + * @returns False if the method is valid, true otherwise. + */ const getIsMethodValid = (method) => { return ( method !== "get" && @@ -33,6 +56,9 @@ method !== "patch" ); }; + /** + * Constants representing various property names and error messages. + */ const SOURCE = `src`; const METHOD = `method`; const ID = `initId`; @@ -57,6 +83,9 @@ }; const MAIN_REGEX = /(\{\{(?:.|\n|\r)*?\}\}|\{\s*\{(?:.|\n|\r)*?\}\s*\})/g; const BRACKET_REGEX = /([{}])|([^{}]+)/g; + /** + * List of request options that are allowed. + */ const requestOptions = [ SOURCE, METHOD, @@ -67,13 +96,20 @@ MEMO, AUTO_BODY ]; - // http codes without successful + /** + * HTTP status codes without successful responses. + */ const codes = [ 100, 101, 102, 103, 300, 301, 302, 303, 304, 305, 306, 307, 308, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 421, 422, 423, 424, 425, 426, 428, 429, 431, 451, 500, 501, 502, 503, 504, 505, 506, 507, 508, 510, 511 ]; + /** + * Parses a string into a HTML template element. + * @param str - The string to parse. + * @returns The first child node of the parsed template. + */ const getTemplateWrapper = (str) => { const elementDocument = new DOMParser().parseFromString( ``, @@ -82,6 +118,11 @@ const elWrapper = elementDocument.childNodes[0].childNodes[0].firstChild; return elWrapper; }; + /** + * Parses the response string into DOM elements, excluding scripts. + * @param response - The response string to parse. + * @returns The parsed template wrapper. + */ const getResponseElements = (response) => { const typeResponse = typeof response; if (typeResponse !== "string") @@ -97,6 +138,21 @@ } return elWrapper; }; + /** + * Makes an HTTP request and handles the response. + * @param el - The element related to the request. + * @param mainEl - The main element in the DOM. + * @param dataObj - The node object containing data. + * @param method - The HTTP method to use. + * @param source - The source URL for the request. + * @param isRequest - Indicates if it's a single request. + * @param isRequests - Indicates if it's multiple requests. + * @param isMemo - Indicates if memoization is enabled. + * @param options - The request initialization options. + * @param templateObject - The template instance. + * @param reqObject - The request object. + * @param indicators - Parsed indicators for the request. + */ const makeRequest = ( el, mainEl, @@ -129,6 +185,7 @@ const initRequest = { method: method.toUpperCase() }; + // Assign optional properties if they are provided if (credentials !== undefined) { initRequest.credentials = credentials; } @@ -165,6 +222,7 @@ `${REQUEST_INIT_ERROR}: The "keepalive" property is not yet supported` ); } + // Handle headers if provided if (headers) { if (checkObject(headers)) { const newHeaders = new Headers(); @@ -190,6 +248,7 @@ ); } } + // Handle timeout and signal if (timeout) { if (!isHaveSignal) { initRequest.signal = AbortSignal.timeout(timeout); @@ -203,6 +262,10 @@ const getIsNotFullfilledStatus = (status) => status === "rejected" || (typeof status === "number" && (status < 200 || status > 299)); + /** + * Calls the 'get' function with the response if provided. + * @param reqResponse - The response to pass to the 'get' function. + */ const callGetResponse = (reqResponse) => { if (isRequests) { reqObject.response = reqResponse; @@ -210,6 +273,12 @@ } get?.("response", mainEl); }; + /** + * Updates the DOM nodes with new content. + * @param content - The content to insert. + * @param isClone - Whether to clone the content. + * @param isNodes - Whether to update nodes in dataObj. + */ const updateNodes = (content, isClone = true, isNodes = false) => { if (isRequest) { templateObject.response = content.cloneNode(true); @@ -258,6 +327,9 @@ }; let isOverlap = false; let isNotHTMLResponse = false; + /** + * Replaces nodes with a comment node. + */ const setComment = () => { if (isRequest) { templateObject.response = undefined; @@ -291,6 +363,10 @@ } } }; + /** + * Updates the indicator based on the request status. + * @param status - The current request status. + */ const updateIndicator = (status) => { if (indicators) { if ( @@ -347,6 +423,10 @@ } } }; + /** + * Updates the status and handles dependencies. + * @param status - The new request status. + */ const updateStatusDepenencies = (status) => { if (isRequests) { if (reqObject.status !== status) { @@ -365,6 +445,9 @@ } updateIndicator(status); }; + /** + * Uses cached nodes if available. + */ const takeNodesFromCache = () => { if (dataObj.memo.isPending) { const parentNode = dataObj.parentNode; @@ -393,6 +476,7 @@ }; let requestStatus = 200; updateStatusDepenencies("pending"); + // Perform the fetch request fetch(source, initRequest) .then((response) => { requestStatus = response.status; @@ -462,6 +546,12 @@ throw error; }); }; + /** + * Executes a HMPLRequestInitFunction to obtain request initialization options. + * @param fn - The function to execute. + * @param event - The event object (if any). + * @returns The HMPLRequestInit object. + */ const getRequestInitFromFn = (fn, event) => { const request = {}; if (event !== undefined) { @@ -473,6 +563,17 @@ const result = fn(context); return result; }; + /** + * Renders the template by processing requests and applying options. + * @param currentEl - The current element or comment node. + * @param fn - The render function. + * @param requests - Array of request objects. + * @param compileOptions - Options provided during compilation. + * @param isMemoUndefined - Indicates if memoization is undefined. + * @param isAutoBodyUndefined - Indicates if autoBody is undefined. + * @param isRequest - Indicates if it's a single request. + * @returns The rendered template function. + */ const renderTemplate = ( currentEl, fn, @@ -561,6 +662,9 @@ } } else { autoBody = false; + createError( + `${REQUEST_OBJECT_ERROR}: The "${AUTO_BODY}" property does not work without the "${AFTER}" property` + ); } } else { if (autoBody === true) { @@ -944,6 +1048,10 @@ } return fn(reqFn); }; + /** + * Validates the options provided for a request. + * @param currentOptions - The options to validate. + */ const validOptions = (currentOptions) => { const isObject = checkObject(currentOptions); if ( @@ -962,6 +1070,10 @@ } } }; + /** + * Validates the autoBody options. + * @param autoBody - The autoBody option to validate. + */ const validAutoBody = (autoBody) => { const isObject = checkObject(autoBody); if (typeof autoBody !== "boolean" && !isObject) @@ -986,6 +1098,10 @@ } } }; + /** + * Validates the HMPLIdentificationRequestInit object. + * @param currentOptions - The identification options to validate. + */ const validIdOptions = (currentOptions) => { if (checkObject(currentOptions)) { if ( @@ -1002,6 +1118,10 @@ ); } }; + /** + * Validates an array of HMPLIdentificationRequestInit objects. + * @param currentOptions - The array of identification options to validate. + */ const validIdentificationOptionsArray = (currentOptions) => { const ids = []; for (let i = 0; i < currentOptions.length; i++) { @@ -1026,9 +1146,20 @@ } } }; + /** + * Converts a HMPLRequestInfo object to a JSON string. + * @param info - The HMPLRequestInfo object. + * @returns The JSON string representation. + */ const stringify = (info) => { - return JSON.stringify(info); + return JSON5.stringify(info); }; + /** + * Compiles a template string into a HMPLTemplateFunction. + * @param template - The template string. + * @param options - The compilation options. + * @returns A function that creates template instances. + */ const compile = (template, options = {}) => { if (typeof template !== "string") createError( @@ -1059,7 +1190,7 @@ return text; }; const setRequest = (text, i) => { - const parsedData = JSON.parse(text); + const parsedData = JSON5.parse(text); for (const key in parsedData) { const value = parsedData[key]; if (!requestOptions.includes(key)) @@ -1233,7 +1364,8 @@ const elWrapper = getTemplateWrapper(template.trim()); if ( elWrapper.content.childNodes.length > 1 || - elWrapper.content.children.length !== 1 + (elWrapper.content.children.length !== 1 && + elWrapper.content.childNodes[0].nodeType !== 8) ) { createError( `${RENDER_ERROR}: Template include only one node with type Element or Comment` diff --git a/dist/hmpl.min.js b/dist/hmpl.min.js index 9a0369c..d88c572 100644 --- a/dist/hmpl.min.js +++ b/dist/hmpl.min.js @@ -1 +1 @@ -!function(e,t){"object"==typeof module&&module.exports?module.exports=t():"function"==typeof define&&define.amd?define([],t):e.hmpl=e.hmpl||t()}("undefined"!=typeof self?self:this,(function(){return function(){"use strict";const e=e=>"object"==typeof e&&!Array.isArray(e)&&null!==e,t=e=>"[object Function]"===Object.prototype.toString.call(e),o=e=>{throw new Error(e)},n=e=>{console.warn(e)},s="method",r="initId",i="after",l="repeat",d="memo",c="indicators",a="autoBody",p="hmpl",f="formData",u="Bad response",h="RequestInit error",m="Render error",y="Request Object error",g="Parse error",b="Compile error",$={formData:!0},v={formData:!1},N=/(\{\{(?:.|\n|\r)*?\}\}|\{\s*\{(?:.|\n|\r)*?\}\s*\})/g,T=/([{}])|([^{}]+)/g,w=["src",s,r,i,l,c,d,a],O=[100,101,102,103,300,301,302,303,304,305,306,307,308,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,421,422,423,424,425,426,428,429,431,451,500,501,502,503,504,505,506,507,508,510,511],j=e=>(new DOMParser).parseFromString(``,"text/html").childNodes[0].childNodes[0].firstChild,P=(t,s,r,i,l,d,c,a,p={},f,y,g)=>{const{mode:b,cache:$,redirect:v,get:N,referrerPolicy:T,signal:w,credentials:O,timeout:P,referrer:E,headers:x,body:k,window:I,integrity:q}=p,C={method:i.toUpperCase()};void 0!==O&&(C.credentials=O),void 0!==k&&(C.body=k),void 0!==b&&(C.mode=b),void 0!==$&&(C.cache=$),void 0!==v&&(C.redirect=v),void 0!==T&&(C.referrerPolicy=T),void 0!==q&&(C.integrity=q),void 0!==E&&(C.referrer=E);const D=void 0!==w;if(D&&(C.signal=w),void 0!==I&&(C.window=I),void 0!==p.keepalive&&n(`${h}: The "keepalive" property is not yet supported`),x)if(e(x)){const e=new Headers;for(const t in x){const n=x[t],s=typeof n;if("string"===s)try{e.set(t,n)}catch(e){throw e}else o(`${h}: Expected type string, but received type ${s}`)}C.headers=e}else o(`${h}: The "headers" property must contain a value object`);P&&(D?n(`${h}: The "signal" property overwrote the AbortSignal from "timeout"`):C.signal=AbortSignal.timeout(P));const R=a&&!d&&r?.memo,A=e=>"rejected"===e||"number"==typeof e&&(e<200||e>299),B=e=>{c&&(y.response=e,N?.("response",e,y)),N?.("response",s)},S=(e,n=!0,s=!1)=>{if(d)f.response=e.cloneNode(!0),N?.("response",e);else{let i=[];const l=(n?e.cloneNode(!0):e).content.childNodes;if(r.nodes){const e=r.parentNode;e||o(`${m}: ParentNode is null`);const t=[],n=r.nodes.length;for(let o=0;o{if(d)f.response=void 0,N?.("response",void 0);else if(r.nodes){const e=r.parentNode;e||o(`${m}: ParentNode is null`);const t=r.nodes.length;for(let o=0;o{c?y.status!==e&&(y.status=e,N?.("status",e,y)):f.status!==e&&(f.status=e,N?.("status",e)),R&&A(e)&&(r.memo.response=null,delete r.memo.nodes),(e=>{if(g)if(R&&"pending"!==e&&A(e)&&r.memo.isPending&&(r.memo.isPending=!1),"pending"===e){const e=g.pending;void 0!==e&&(R&&(r.memo.isPending=!0),S(e))}else if("rejected"===e){const e=g.rejected;if(void 0!==e)S(e);else{const e=g.error;void 0!==e?S(e):H()}}else{const t=g[`${e}`];if(e>399)if(M=!0,void 0!==t)S(t);else{const e=g.error;void 0!==e?S(e):H()}else(e<200||e>299)&&(F=!0,void 0!==t?S(t):H())}})(e)};let z=200;L("pending"),fetch(l,C).then((e=>(z=e.status,L(z),e.ok||o(`${u}: Response with status code ${z}`),e.text()))).then((e=>{if(!F)if(A(z))H();else{if(R){const{response:t}=r.memo;if(null===t)r.memo.response=e;else{if(t===e)return void(()=>{if(r.memo.isPending){const e=r.parentNode;e||o(`${m}: ParentNode is null`);const t=r.memo.nodes,n=r.nodes,s=n.length,i=[];for(let o=0;o{const t=typeof e;"string"!==t&&o(`${u}: Expected type string, but received type ${t}`);const n=j(e),s=n.content,r=s.querySelectorAll("script");for(let e=0;e{throw M||(L("rejected"),g||H()),e}))},E=t=>{const n=e(t);if("boolean"==typeof t||n||o(`${y}: Expected a boolean or object, but got neither`),n)for(const e in t)if(e===f)"boolean"!=typeof t[f]&&o(`${y}: The "${f}" property should be a boolean`);else o(`${y}: Unexpected property "${e}"`)},x=t=>{e(t)?t.hasOwnProperty("id")&&t.hasOwnProperty("value")||o(`${y}: Missing "id" or "value" property`):o(`${y}: IdentificationRequestInit must be of type object`)};return{compile:(n,f={})=>{"string"!=typeof n&&o(`${b}: Template was not found or the type of the passed value is not string`),n||o(`${b}: Template must not be a falsey value`),e(f)||o(`${b}: Options must be an object`);const u=!f.hasOwnProperty(d);u||"boolean"==typeof f[d]||o(`${y}: The value of the property ${d} must be a boolean value`);const k=!f.hasOwnProperty(a);k||E(f[a]);const I=[],q=n.split(N).filter(Boolean),C=[];for(const e of n.matchAll(N))C.push(e.index);0===C.length&&o(`${g}: Request not found`);const D=e=>e=(e=e.trim()).replace(/\r?\n|\r/g,""),R=(e,t)=>{const n=JSON.parse(e);for(const e in n){const t=n[e];switch(w.includes(e)||o(`${y}: Property "${e}" is not processed`),e){case c:Array.isArray(t)||o(`${y}: The value of the property "${e}" must be an array`);break;case r:"string"!=typeof t&&"number"!=typeof t&&o(`${y}: The value of the property "${e}" must be a string`);break;case d:case l:"boolean"!=typeof t&&o(`${y}: The value of the property "${e}" must be a boolean value`);break;case a:E(t);break;default:"string"!=typeof t&&o(`${y}: The value of the property "${e}" must be a string`)}}const s={...n,arrId:t};I.push(s)};let A=0;for(let e=0;e{const t=j(e.trim());(t.content.childNodes.length>1||1!==t.content.children.length)&&o(`${m}: Template include only one node with type Element or Comment`);const n=e=>{switch(e.nodeType){case Node.ELEMENT_NODE:if("pre"===e.tagName)return;break;case Node.TEXT_NODE:if(!/\S/.test(e.textContent))return void e.remove()}for(let t=0;t{const N=(n,r)=>{const c=n.src;if(c){const p=(n.method||"GET").toLowerCase();if(!(e=>"get"!==e&&"post"!==e&&"put"!==e&&"delete"!==e&&"patch"!==e)(p)){const s=n.after;s&&b&&o(`${m}: EventTarget is undefined`);const N=!n.hasOwnProperty(l);N||"boolean"==typeof n.repeat||o(`${y}: The "${l}" property has only boolean value`);const T="all"==(N||n.repeat?"all":"one"),w=!n.hasOwnProperty(d);let x=!u&&f.memo;w?x&&(s&&T||(x=!1)):s?n.memo?T?x=!0:o(`${y}: Memoization works in the enabled repetition mode`):x=!1:o(`${y}: Memoization works in the enabled repetition mode`);const k=!n.hasOwnProperty(a);let I=!g&&f.autoBody;if(k)!0===I&&(I=$),s||(I=!1);else if(s){let e=n[a];if(E(e),!0===I&&(I=$),!0===e&&(e=$),!1===e)I=!1;else{const t={...!1===I?v:I,...e};I=t}}else I=!1;const q=n.initId,C=n.nodeId;let D=n.indicators;if(D){const e=e=>{const{trigger:t,content:n}=e;t||o(`${y}: Failed to activate or detect the indicator`),n||o(`${y}: Failed to activate or detect the indicator`),-1===O.indexOf(t)&&"pending"!==t&&"rejected"!==t&&"error"!==t&&o(`${y}: Failed to activate or detect the indicator`);const s=j(n);return{...e,content:s}},t={},n=[];for(let s=0;s{if(t){if(q){let t;for(let o=0;o{const $=l.currentId;if(b)n||(n=r);else if(!n)if(y)n=y.el;else{let e;const{els:t}=l;for(let o=0;o{const o={};return void 0!==t&&(o.event=t),e({request:o})})(N,g):N;e(w)||void 0===w||o(`${h}: Expected an object with initialization options`),P(n,d,v,p,c,b,u,x,w,i,f,D)};let S=B;if(s){const e=(e,t,n,s,r,i,l,d,c,a,p)=>{const f=c.querySelectorAll(n);0===f.length&&o(`${m}: Selectors nodes not found`);const u=T?t=>{B(e,s,r,i,c,l,a,d,p,t)}:o=>{B(e,s,r,i,c,l,a,d,p,o);for(let e=0;e0){const t=s.split(":"),o=t[0],n=t.slice(1).join(":");S=(t,s,r,i,l,d=!1,c,a=!1,p)=>{e(t,o,n,s,r,i,d,a,l,c,p)}}else o(`${y}: The "${i}" property doesn't work without EventTargets`)}else N||o(`${y}: The "${l}" property doesn't work without "${i}" property`);return S}o(`${y}: The "${s}" property has only GET, POST, PUT, PATCH or DELETE values`)}else o(`${y}: The "source" property are not found or empty`)};let T;if(b)c[0].el=n,T=N(c[0]);else{let e=-2;const t=n=>{if(e++,8==n.nodeType){let t=n.nodeValue;if(t&&t.startsWith(p)){t=t.slice(4);const s=Number(t),r=c[s];(Number.isNaN(s)||void 0===r)&&o(`${m}: Request object not found`),r.el=n,r.nodeId=e}}if(n.hasChildNodes()){const e=n.childNodes;for(let o=0;o1)T=(e,t,n,r,i,l=!1)=>{e||(e=i);const d=[],c=r.els;for(let i=0;i(s={})=>{const r=S.cloneNode(!0),i={response:B?void 0:r},l={dataObjects:[],els:[],currentId:0};if(!B){let e=-2;const t=o=>{if(e++,8==o.nodeType){const t=o.nodeValue;if(t&&t.startsWith(p)){const t={el:o,id:e};l.els.push(t)}}if(o.hasChildNodes()){const e=o.childNodes;for(let o=0;o{const s=e(n);s||t(n)||void 0===n||o(`${h}: Expected an object with initialization options`),s&&n.get&&(t(n.get)||o(`${h}: The "get" property has a function value`))})(s),n(void 0,s,i,l,r)):Array.isArray(s)&&((t=>{const n=[];for(let s=0;s-1?o(`${y}: ID with value "${i}" already exists`):n.push(i)}})(s),n(void 0,s,i,l,r,!0)),i}),I,f,u,k,B)},stringify:e=>JSON.stringify(e)}}()})); \ No newline at end of file +!function(e,t){"object"==typeof module&&module.exports?module.exports=t():"function"==typeof define&&define.amd?define([],t):e.hmpl=e.hmpl||t()}("undefined"!=typeof self?self:this,(function(){return function(){"use strict";const e=e=>"object"==typeof e&&!Array.isArray(e)&&null!==e,t=e=>"[object Function]"===Object.prototype.toString.call(e),o=e=>{throw new Error(e)},n=e=>{console.warn(e)},s="method",r="initId",i="after",l="repeat",d="memo",c="indicators",a="autoBody",p="hmpl",f="formData",u="Bad response",h="RequestInit error",m="Render error",y="Request Object error",g="Parse error",$="Compile error",b={formData:!0},v={formData:!1},N=/(\{\{(?:.|\n|\r)*?\}\}|\{\s*\{(?:.|\n|\r)*?\}\s*\})/g,T=/([{}])|([^{}]+)/g,w=["src",s,r,i,l,c,d,a],O=[100,101,102,103,300,301,302,303,304,305,306,307,308,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,421,422,423,424,425,426,428,429,431,451,500,501,502,503,504,505,506,507,508,510,511],j=e=>(new DOMParser).parseFromString(``,"text/html").childNodes[0].childNodes[0].firstChild,P=(t,s,r,i,l,d,c,a,p={},f,y,g)=>{const{mode:$,cache:b,redirect:v,get:N,referrerPolicy:T,signal:w,credentials:O,timeout:P,referrer:E,headers:k,body:x,window:I,integrity:q}=p,C={method:i.toUpperCase()};void 0!==O&&(C.credentials=O),void 0!==x&&(C.body=x),void 0!==$&&(C.mode=$),void 0!==b&&(C.cache=b),void 0!==v&&(C.redirect=v),void 0!==T&&(C.referrerPolicy=T),void 0!==q&&(C.integrity=q),void 0!==E&&(C.referrer=E);const D=void 0!==w;if(D&&(C.signal=w),void 0!==I&&(C.window=I),void 0!==p.keepalive&&n(`${h}: The "keepalive" property is not yet supported`),k)if(e(k)){const e=new Headers;for(const t in k){const n=k[t],s=typeof n;if("string"===s)try{e.set(t,n)}catch(e){throw e}else o(`${h}: Expected type string, but received type ${s}`)}C.headers=e}else o(`${h}: The "headers" property must contain a value object`);P&&(D?n(`${h}: The "signal" property overwrote the AbortSignal from "timeout"`):C.signal=AbortSignal.timeout(P));const R=a&&!d&&r?.memo,A=e=>"rejected"===e||"number"==typeof e&&(e<200||e>299),B=e=>{c&&(y.response=e,N?.("response",e,y)),N?.("response",s)},S=(e,n=!0,s=!1)=>{if(d)f.response=e.cloneNode(!0),N?.("response",e);else{let i=[];const l=(n?e.cloneNode(!0):e).content.childNodes;if(r.nodes){const e=r.parentNode;e||o(`${m}: ParentNode is null`);const t=[],n=r.nodes.length;for(let o=0;o{if(d)f.response=void 0,N?.("response",void 0);else if(r.nodes){const e=r.parentNode;e||o(`${m}: ParentNode is null`);const t=r.nodes.length;for(let o=0;o{c?y.status!==e&&(y.status=e,N?.("status",e,y)):f.status!==e&&(f.status=e,N?.("status",e)),R&&A(e)&&(r.memo.response=null,delete r.memo.nodes),(e=>{if(g)if(R&&"pending"!==e&&A(e)&&r.memo.isPending&&(r.memo.isPending=!1),"pending"===e){const e=g.pending;void 0!==e&&(R&&(r.memo.isPending=!0),S(e))}else if("rejected"===e){const e=g.rejected;if(void 0!==e)S(e);else{const e=g.error;void 0!==e?S(e):H()}}else{const t=g[`${e}`];if(e>399)if(M=!0,void 0!==t)S(t);else{const e=g.error;void 0!==e?S(e):H()}else(e<200||e>299)&&(F=!0,void 0!==t?S(t):H())}})(e)};let z=200;L("pending"),fetch(l,C).then((e=>(z=e.status,L(z),e.ok||o(`${u}: Response with status code ${z}`),e.text()))).then((e=>{if(!F)if(A(z))H();else{if(R){const{response:t}=r.memo;if(null===t)r.memo.response=e;else{if(t===e)return void(()=>{if(r.memo.isPending){const e=r.parentNode;e||o(`${m}: ParentNode is null`);const t=r.memo.nodes,n=r.nodes,s=n.length,i=[];for(let o=0;o{const t=typeof e;"string"!==t&&o(`${u}: Expected type string, but received type ${t}`);const n=j(e),s=n.content,r=s.querySelectorAll("script");for(let e=0;e{throw M||(L("rejected"),g||H()),e}))},E=t=>{const n=e(t);if("boolean"==typeof t||n||o(`${y}: Expected a boolean or object, but got neither`),n)for(const e in t)if(e===f)"boolean"!=typeof t[f]&&o(`${y}: The "${f}" property should be a boolean`);else o(`${y}: Unexpected property "${e}"`)},k=t=>{e(t)?t.hasOwnProperty("id")&&t.hasOwnProperty("value")||o(`${y}: Missing "id" or "value" property`):o(`${y}: IdentificationRequestInit must be of type object`)};return{compile:(n,f={})=>{"string"!=typeof n&&o(`${$}: Template was not found or the type of the passed value is not string`),n||o(`${$}: Template must not be a falsey value`),e(f)||o(`${$}: Options must be an object`);const u=!f.hasOwnProperty(d);u||"boolean"==typeof f[d]||o(`${y}: The value of the property ${d} must be a boolean value`);const x=!f.hasOwnProperty(a);x||E(f[a]);const I=[],q=n.split(N).filter(Boolean),C=[];for(const e of n.matchAll(N))C.push(e.index);0===C.length&&o(`${g}: Request not found`);const D=e=>e=(e=e.trim()).replace(/\r?\n|\r/g,""),R=(e,t)=>{const n=JSON5.parse(e);for(const e in n){const t=n[e];switch(w.includes(e)||o(`${y}: Property "${e}" is not processed`),e){case c:Array.isArray(t)||o(`${y}: The value of the property "${e}" must be an array`);break;case r:"string"!=typeof t&&"number"!=typeof t&&o(`${y}: The value of the property "${e}" must be a string`);break;case d:case l:"boolean"!=typeof t&&o(`${y}: The value of the property "${e}" must be a boolean value`);break;case a:E(t);break;default:"string"!=typeof t&&o(`${y}: The value of the property "${e}" must be a string`)}}const s={...n,arrId:t};I.push(s)};let A=0;for(let e=0;e{const t=j(e.trim());(t.content.childNodes.length>1||1!==t.content.children.length&&8!==t.content.childNodes[0].nodeType)&&o(`${m}: Template include only one node with type Element or Comment`);const n=e=>{switch(e.nodeType){case Node.ELEMENT_NODE:if("pre"===e.tagName)return;break;case Node.TEXT_NODE:if(!/\S/.test(e.textContent))return void e.remove()}for(let t=0;t{const N=(n,r)=>{const c=n.src;if(c){const p=(n.method||"GET").toLowerCase();if(!(e=>"get"!==e&&"post"!==e&&"put"!==e&&"delete"!==e&&"patch"!==e)(p)){const s=n.after;s&&$&&o(`${m}: EventTarget is undefined`);const N=!n.hasOwnProperty(l);N||"boolean"==typeof n.repeat||o(`${y}: The "${l}" property has only boolean value`);const T="all"==(N||n.repeat?"all":"one"),w=!n.hasOwnProperty(d);let k=!u&&f.memo;w?k&&(s&&T||(k=!1)):s?n.memo?T?k=!0:o(`${y}: Memoization works in the enabled repetition mode`):k=!1:o(`${y}: Memoization works in the enabled repetition mode`);const x=!n.hasOwnProperty(a);let I=!g&&f.autoBody;if(x)!0===I&&(I=b),s||(I=!1);else if(s){let e=n[a];if(E(e),!0===I&&(I=b),!0===e&&(e=b),!1===e)I=!1;else{const t={...!1===I?v:I,...e};I=t}}else I=!1,o(`${y}: The "${a}" property does not work without the "${i}" property`);const q=n.initId,C=n.nodeId;let D=n.indicators;if(D){const e=e=>{const{trigger:t,content:n}=e;t||o(`${y}: Failed to activate or detect the indicator`),n||o(`${y}: Failed to activate or detect the indicator`),-1===O.indexOf(t)&&"pending"!==t&&"rejected"!==t&&"error"!==t&&o(`${y}: Failed to activate or detect the indicator`);const s=j(n);return{...e,content:s}},t={},n=[];for(let s=0;s{if(t){if(q){let t;for(let o=0;o{const b=l.currentId;if($)n||(n=r);else if(!n)if(y)n=y.el;else{let e;const{els:t}=l;for(let o=0;o{const o={};return void 0!==t&&(o.event=t),e({request:o})})(N,g):N;e(w)||void 0===w||o(`${h}: Expected an object with initialization options`),P(n,d,v,p,c,$,u,k,w,i,f,D)};let S=B;if(s){const e=(e,t,n,s,r,i,l,d,c,a,p)=>{const f=c.querySelectorAll(n);0===f.length&&o(`${m}: Selectors nodes not found`);const u=T?t=>{B(e,s,r,i,c,l,a,d,p,t)}:o=>{B(e,s,r,i,c,l,a,d,p,o);for(let e=0;e0){const t=s.split(":"),o=t[0],n=t.slice(1).join(":");S=(t,s,r,i,l,d=!1,c,a=!1,p)=>{e(t,o,n,s,r,i,d,a,l,c,p)}}else o(`${y}: The "${i}" property doesn't work without EventTargets`)}else N||o(`${y}: The "${l}" property doesn't work without "${i}" property`);return S}o(`${y}: The "${s}" property has only GET, POST, PUT, PATCH or DELETE values`)}else o(`${y}: The "source" property are not found or empty`)};let T;if($)c[0].el=n,T=N(c[0]);else{let e=-2;const t=n=>{if(e++,8==n.nodeType){let t=n.nodeValue;if(t&&t.startsWith(p)){t=t.slice(4);const s=Number(t),r=c[s];(Number.isNaN(s)||void 0===r)&&o(`${m}: Request object not found`),r.el=n,r.nodeId=e}}if(n.hasChildNodes()){const e=n.childNodes;for(let o=0;o1)T=(e,t,n,r,i,l=!1)=>{e||(e=i);const d=[],c=r.els;for(let i=0;i(s={})=>{const r=S.cloneNode(!0),i={response:B?void 0:r},l={dataObjects:[],els:[],currentId:0};if(!B){let e=-2;const t=o=>{if(e++,8==o.nodeType){const t=o.nodeValue;if(t&&t.startsWith(p)){const t={el:o,id:e};l.els.push(t)}}if(o.hasChildNodes()){const e=o.childNodes;for(let o=0;o{const s=e(n);s||t(n)||void 0===n||o(`${h}: Expected an object with initialization options`),s&&n.get&&(t(n.get)||o(`${h}: The "get" property has a function value`))})(s),n(void 0,s,i,l,r)):Array.isArray(s)&&((t=>{const n=[];for(let s=0;s-1?o(`${y}: ID with value "${i}" already exists`):n.push(i)}})(s),n(void 0,s,i,l,r,!0)),i}),I,f,u,x,B)},stringify:e=>JSON5.stringify(e)}}()})); \ No newline at end of file diff --git a/dist/hmpl.runtime.js b/dist/hmpl.runtime.js index 3745c7e..4e52839 100644 --- a/dist/hmpl.runtime.js +++ b/dist/hmpl.runtime.js @@ -1,763 +1,818 @@ -(function (root, factory) { - if (typeof module === "object" && module.exports) { - module.exports = factory(); - //@ts-expect-error define not found - } else if (typeof define === "function" && define.amd) { - //@ts-expect-error define not found - define([], factory); - } else { - //@ts-expect-error root.hmpl not found - root.hmpl = root.hmpl || factory(); +"use strict"; +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } -})(typeof self !== "undefined" ? self : this, function () { - return (function () { - "use strict"; - const checkObject = (val) => { - return typeof val === "object" && !Array.isArray(val) && val !== null; - }; - const checkFunction = (val) => { - return Object.prototype.toString.call(val) === "[object Function]"; - }; - const createError = (text) => { - throw new Error(text); - }; - const createWarning = (text) => { - console.warn(text); - }; - const getIsMethodValid = (method) => { - return ( - method !== "get" && - method !== "post" && - method !== "put" && - method !== "delete" && - method !== "patch" + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +var main_exports = {}; +__export(main_exports, { + compile: () => compile, + stringify: () => stringify +}); +module.exports = __toCommonJS(main_exports); +var import_json5 = __toESM(require("json5")); +var checkObject = (val) => { + return typeof val === "object" && !Array.isArray(val) && val !== null; +}; +var checkFunction = (val) => { + return Object.prototype.toString.call(val) === "[object Function]"; +}; +var createError = (text) => { + throw new Error(text); +}; +var createWarning = (text) => { + console.warn(text); +}; +var getIsMethodValid = (method) => { + return method !== "get" && method !== "post" && method !== "put" && method !== "delete" && method !== "patch"; +}; +var SOURCE = `src`; +var METHOD = `method`; +var ID = `initId`; +var AFTER = `after`; +var MODE = `repeat`; +var MEMO = `memo`; +var INDICATORS = `indicators`; +var AUTO_BODY = `autoBody`; +var COMMENT = `hmpl`; +var FORM_DATA = `formData`; +var RESPONSE_ERROR = `Bad response`; +var REQUEST_INIT_ERROR = `RequestInit error`; +var RENDER_ERROR = `Render error`; +var REQUEST_OBJECT_ERROR = `Request Object error`; +var PARSE_ERROR = `Parse error`; +var COMPILE_ERROR = `Compile error`; +var DEFAULT_AUTO_BODY = { + formData: true +}; +var DEFAULT_FALSE_AUTO_BODY = { + formData: false +}; +var MAIN_REGEX = /(\{\{(?:.|\n|\r)*?\}\}|\{\s*\{(?:.|\n|\r)*?\}\s*\})/g; +var BRACKET_REGEX = /([{}])|([^{}]+)/g; +var requestOptions = [ + SOURCE, + METHOD, + ID, + AFTER, + MODE, + INDICATORS, + MEMO, + AUTO_BODY +]; +var codes = [ + 100, + 101, + 102, + 103, + 300, + 301, + 302, + 303, + 304, + 305, + 306, + 307, + 308, + 400, + 401, + 402, + 403, + 404, + 405, + 406, + 407, + 408, + 409, + 410, + 411, + 412, + 413, + 414, + 415, + 416, + 417, + 418, + 421, + 422, + 423, + 424, + 425, + 426, + 428, + 429, + 431, + 451, + 500, + 501, + 502, + 503, + 504, + 505, + 506, + 507, + 508, + 510, + 511 +]; +var getTemplateWrapper = (str) => { + const elementDocument = new DOMParser().parseFromString( + ``, + "text/html" + ); + const elWrapper = elementDocument.childNodes[0].childNodes[0].firstChild; + return elWrapper; +}; +var getResponseElements = (response) => { + const typeResponse = typeof response; + if (typeResponse !== "string") + createError( + `${RESPONSE_ERROR}: Expected type string, but received type ${typeResponse}` + ); + const elWrapper = getTemplateWrapper(response); + const elContent = elWrapper["content"]; + const scripts = elContent.querySelectorAll("script"); + for (let i = 0; i < scripts.length; i++) { + const currentScript = scripts[i]; + elContent.removeChild(currentScript); + } + return elWrapper; +}; +var makeRequest = (el, mainEl, dataObj, method, source, isRequest, isRequests, isMemo, options = {}, templateObject, reqObject, indicators) => { + const { + mode, + cache, + redirect, + get, + referrerPolicy, + signal, + credentials, + timeout, + referrer, + headers, + body, + window: windowOption, + integrity + } = options; + const initRequest = { + method: method.toUpperCase() + }; + if (credentials !== void 0) { + initRequest.credentials = credentials; + } + if (body !== void 0) { + initRequest.body = body; + } + if (mode !== void 0) { + initRequest.mode = mode; + } + if (cache !== void 0) { + initRequest.cache = cache; + } + if (redirect !== void 0) { + initRequest.redirect = redirect; + } + if (referrerPolicy !== void 0) { + initRequest.referrerPolicy = referrerPolicy; + } + if (integrity !== void 0) { + initRequest.integrity = integrity; + } + if (referrer !== void 0) { + initRequest.referrer = referrer; + } + const isHaveSignal = signal !== void 0; + if (isHaveSignal) { + initRequest.signal = signal; + } + if (windowOption !== void 0) { + initRequest.window = windowOption; + } + if (options.keepalive !== void 0) { + createWarning( + `${REQUEST_INIT_ERROR}: The "keepalive" property is not yet supported` + ); + } + if (headers) { + if (checkObject(headers)) { + const newHeaders = new Headers(); + for (const key in headers) { + const value = headers[key]; + const valueType = typeof value; + if (valueType === "string") { + try { + newHeaders.set(key, value); + } catch (e) { + throw e; + } + } else { + createError( + `${REQUEST_INIT_ERROR}: Expected type string, but received type ${valueType}` + ); + } + } + initRequest.headers = newHeaders; + } else { + createError( + `${REQUEST_INIT_ERROR}: The "headers" property must contain a value object` ); - }; - const SOURCE = `src`; - const METHOD = `method`; - const ID = `initId`; - const AFTER = `after`; - const MODE = `repeat`; - const MEMO = `memo`; - const INDICATORS = `indicators`; - const AUTO_BODY = `autoBody`; - const COMMENT = `hmpl`; - const FORM_DATA = `formData`; - const RESPONSE_ERROR = `Bad response`; - const REQUEST_INIT_ERROR = `RequestInit error`; - const RENDER_ERROR = `Render error`; - const REQUEST_OBJECT_ERROR = `Request Object error`; - const PARSE_ERROR = `Parse error`; - const COMPILE_ERROR = `Compile error`; - const DEFAULT_AUTO_BODY = { - formData: true - }; - const DEFAULT_FALSE_AUTO_BODY = { - formData: false - }; - const MAIN_REGEX = /(\{\{(?:.|\n|\r)*?\}\}|\{\s*\{(?:.|\n|\r)*?\}\s*\})/g; - const BRACKET_REGEX = /([{}])|([^{}]+)/g; - const requestOptions = [ - SOURCE, - METHOD, - ID, - AFTER, - MODE, - INDICATORS, - MEMO, - AUTO_BODY - ]; - // http codes without successful - const codes = [ - 100, 101, 102, 103, 300, 301, 302, 303, 304, 305, 306, 307, 308, 400, 401, - 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, - 417, 418, 421, 422, 423, 424, 425, 426, 428, 429, 431, 451, 500, 501, 502, - 503, 504, 505, 506, 507, 508, 510, 511 - ]; - const getTemplateWrapper = (str) => { - const elementDocument = new DOMParser().parseFromString( - ``, - "text/html" + } + } + if (timeout) { + if (!isHaveSignal) { + initRequest.signal = AbortSignal.timeout(timeout); + } else { + createWarning( + `${REQUEST_INIT_ERROR}: The "signal" property overwrote the AbortSignal from "timeout"` ); - const elWrapper = elementDocument.childNodes[0].childNodes[0].firstChild; - return elWrapper; - }; - const getResponseElements = (response) => { - const typeResponse = typeof response; - if (typeResponse !== "string") - createError( - `${RESPONSE_ERROR}: Expected type string, but received type ${typeResponse}` - ); - const elWrapper = getTemplateWrapper(response); - const elContent = elWrapper["content"]; - const scripts = elContent.querySelectorAll("script"); - for (let i = 0; i < scripts.length; i++) { - const currentScript = scripts[i]; - elContent.removeChild(currentScript); - } - return elWrapper; - }; - const makeRequest = ( - el, - mainEl, - dataObj, - method, - source, - isRequest, - isRequests, - isMemo, - options = {}, - templateObject, - reqObject, - indicators - ) => { - const { - mode, - cache, - redirect, - get, - referrerPolicy, - signal, - credentials, - timeout, - referrer, - headers, - body, - window: windowOption, - integrity - } = options; - const initRequest = { - method: method.toUpperCase() - }; - if (credentials !== undefined) { - initRequest.credentials = credentials; - } - if (body !== undefined) { - initRequest.body = body; - } - if (mode !== undefined) { - initRequest.mode = mode; - } - if (cache !== undefined) { - initRequest.cache = cache; - } - if (redirect !== undefined) { - initRequest.redirect = redirect; - } - if (referrerPolicy !== undefined) { - initRequest.referrerPolicy = referrerPolicy; - } - if (integrity !== undefined) { - initRequest.integrity = integrity; + } + } + const isRequestMemo = isMemo && !isRequest && dataObj?.memo; + const getIsNotFullfilledStatus = (status) => status === "rejected" || typeof status === "number" && (status < 200 || status > 299); + const callGetResponse = (reqResponse) => { + if (isRequests) { + reqObject.response = reqResponse; + get?.("response", reqResponse, reqObject); + } + get?.("response", mainEl); + }; + const updateNodes = (content, isClone = true, isNodes = false) => { + if (isRequest) { + templateObject.response = content.cloneNode(true); + get?.("response", content); + } else { + let reqResponse = []; + const newContent = isClone ? content.cloneNode(true) : content; + const nodes = newContent.content.childNodes; + if (dataObj.nodes) { + const parentNode = dataObj.parentNode; + if (!parentNode) createError(`${RENDER_ERROR}: ParentNode is null`); + const newNodes = []; + const nodesLength = dataObj.nodes.length; + for (let i = 0; i < nodesLength; i++) { + const node = dataObj.nodes[i]; + if (i === nodesLength - 1) { + for (let j = 0; j < nodes.length; j++) { + const reqNode = nodes[j]; + const newNode = parentNode.insertBefore(reqNode, node); + newNodes.push(newNode); + } + } + parentNode.removeChild(node); + } + reqResponse = newNodes.slice(); + dataObj.nodes = newNodes; + } else { + const parentNode = el.parentNode; + const newNodes = []; + for (let i = 0; i < nodes.length; i++) { + const node = nodes[i]; + const newNode = parentNode.insertBefore(node, el); + newNodes.push(newNode); + } + parentNode.removeChild(el); + reqResponse = newNodes.slice(); + dataObj.nodes = newNodes; + dataObj.parentNode = parentNode; } - if (referrer !== undefined) { - initRequest.referrer = referrer; + if (isRequestMemo && isNodes) { + dataObj.memo.nodes = dataObj.nodes; + if (dataObj.memo.isPending) dataObj.memo.isPending = false; } - const isHaveSignal = signal !== undefined; - if (isHaveSignal) { - initRequest.signal = signal; + callGetResponse(reqResponse); + } + }; + let isOverlap = false; + let isNotHTMLResponse = false; + const setComment = () => { + if (isRequest) { + templateObject.response = void 0; + get?.("response", void 0); + } else { + if (dataObj.nodes) { + const parentNode = dataObj.parentNode; + if (!parentNode) createError(`${RENDER_ERROR}: ParentNode is null`); + const nodesLength = dataObj.nodes.length; + for (let i = 0; i < nodesLength; i++) { + const node = dataObj.nodes[i]; + if (i === nodesLength - 1) { + parentNode.insertBefore(dataObj.comment, node); + } + parentNode.removeChild(node); + } + dataObj.nodes = null; + dataObj.parentNode = null; + if (isRequests) { + reqObject.response = void 0; + get?.("response", void 0, reqObject); + } + get?.("response", mainEl); } - if (windowOption !== undefined) { - initRequest.window = windowOption; + } + if (isRequestMemo) { + if (dataObj.memo.response !== null) { + dataObj.memo.response = null; + delete dataObj.memo.isPending; + delete dataObj.memo.nodes; } - if (options.keepalive !== undefined) { - createWarning( - `${REQUEST_INIT_ERROR}: The "keepalive" property is not yet supported` - ); + } + }; + const updateIndicator = (status) => { + if (indicators) { + if (isRequestMemo && status !== "pending" && getIsNotFullfilledStatus(status)) { + if (dataObj.memo.isPending) dataObj.memo.isPending = false; } - if (headers) { - if (checkObject(headers)) { - const newHeaders = new Headers(); - for (const key in headers) { - const value = headers[key]; - const valueType = typeof value; - if (valueType === "string") { - try { - newHeaders.set(key, value); - } catch (e) { - throw e; - } + if (status === "pending") { + const content = indicators["pending"]; + if (content !== void 0) { + if (isRequestMemo) { + dataObj.memo.isPending = true; + } + updateNodes(content); + } + } else if (status === "rejected") { + const content = indicators["rejected"]; + if (content !== void 0) { + updateNodes(content); + } else { + const errorContent = indicators["error"]; + if (errorContent !== void 0) { + updateNodes(errorContent); + } else { + setComment(); + } + } + } else { + const content = indicators[`${status}`]; + if (status > 399) { + isOverlap = true; + if (content !== void 0) { + updateNodes(content); + } else { + const errorContent = indicators["error"]; + if (errorContent !== void 0) { + updateNodes(errorContent); } else { - createError( - `${REQUEST_INIT_ERROR}: Expected type string, but received type ${valueType}` - ); + setComment(); } } - initRequest.headers = newHeaders; } else { - createError( - `${REQUEST_INIT_ERROR}: The "headers" property must contain a value object` - ); + if (status < 200 || status > 299) { + isNotHTMLResponse = true; + if (content !== void 0) { + updateNodes(content); + } else { + setComment(); + } + } } } - if (timeout) { - if (!isHaveSignal) { - initRequest.signal = AbortSignal.timeout(timeout); - } else { - createWarning( - `${REQUEST_INIT_ERROR}: The "signal" property overwrote the AbortSignal from "timeout"` - ); + } + }; + const updateStatusDepenencies = (status) => { + if (isRequests) { + if (reqObject.status !== status) { + reqObject.status = status; + get?.("status", status, reqObject); + } + } else { + if (templateObject.status !== status) { + templateObject.status = status; + get?.("status", status); + } + } + if (isRequestMemo && getIsNotFullfilledStatus(status)) { + dataObj.memo.response = null; + delete dataObj.memo.nodes; + } + updateIndicator(status); + }; + const takeNodesFromCache = () => { + if (dataObj.memo.isPending) { + const parentNode = dataObj.parentNode; + if (!parentNode) createError(`${RENDER_ERROR}: ParentNode is null`); + const memoNodes = dataObj.memo.nodes; + const currentNodes = dataObj.nodes; + const nodesLength = currentNodes.length; + const newNodes = []; + for (let i = 0; i < nodesLength; i++) { + const node = currentNodes[i]; + if (i === nodesLength - 1) { + for (let j = 0; j < memoNodes.length; j++) { + const reqNode = memoNodes[j]; + const newNode = parentNode.insertBefore(reqNode, node); + newNodes.push(newNode); + } } + parentNode.removeChild(node); } - const isRequestMemo = isMemo && !isRequest && dataObj?.memo; - const getIsNotFullfilledStatus = (status) => - status === "rejected" || - (typeof status === "number" && (status < 200 || status > 299)); - const callGetResponse = (reqResponse) => { - if (isRequests) { - reqObject.response = reqResponse; - get?.("response", reqResponse, reqObject); + dataObj.nodes = newNodes.slice(); + dataObj.memo.isPending = false; + dataObj.memo.nodes = newNodes.slice(); + } + const reqResponse = dataObj.nodes.slice(); + callGetResponse(reqResponse); + }; + let requestStatus = 200; + updateStatusDepenencies("pending"); + fetch(source, initRequest).then((response) => { + requestStatus = response.status; + updateStatusDepenencies(requestStatus); + if (!response.ok) { + createError( + `${RESPONSE_ERROR}: Response with status code ${requestStatus}` + ); + } + return response.text(); + }).then((data) => { + if (!isNotHTMLResponse) { + if (!getIsNotFullfilledStatus(requestStatus)) { + if (isRequestMemo) { + const { response } = dataObj.memo; + if (response === null) { + dataObj.memo.response = data; + } else { + if (response === data) { + takeNodesFromCache(); + return; + } else { + dataObj.memo.response = data; + delete dataObj.memo.nodes; + } + } } - get?.("response", mainEl); - }; - const updateNodes = (content, isClone = true, isNodes = false) => { + const templateWrapper = getResponseElements(data); if (isRequest) { - templateObject.response = content.cloneNode(true); - get?.("response", content); + templateObject.response = templateWrapper; + get?.("response", templateWrapper); } else { - let reqResponse = []; - const newContent = isClone ? content.cloneNode(true) : content; - const nodes = newContent.content.childNodes; - if (dataObj.nodes) { - const parentNode = dataObj.parentNode; - if (!parentNode) createError(`${RENDER_ERROR}: ParentNode is null`); - const newNodes = []; - const nodesLength = dataObj.nodes.length; - for (let i = 0; i < nodesLength; i++) { - const node = dataObj.nodes[i]; - if (i === nodesLength - 1) { - for (let j = 0; j < nodes.length; j++) { - const reqNode = nodes[j]; - const newNode = parentNode.insertBefore(reqNode, node); - newNodes.push(newNode); - } - } - parentNode.removeChild(node); - } - reqResponse = newNodes.slice(); - dataObj.nodes = newNodes; + const reqResponse = []; + const nodes = templateWrapper.content.childNodes; + if (dataObj) { + updateNodes(templateWrapper, false, true); } else { const parentNode = el.parentNode; - const newNodes = []; for (let i = 0; i < nodes.length; i++) { const node = nodes[i]; - const newNode = parentNode.insertBefore(node, el); - newNodes.push(newNode); - } - parentNode.removeChild(el); - reqResponse = newNodes.slice(); - dataObj.nodes = newNodes; - dataObj.parentNode = parentNode; - } - if (isRequestMemo && isNodes) { - dataObj.memo.nodes = dataObj.nodes; - if (dataObj.memo.isPending) dataObj.memo.isPending = false; - } - callGetResponse(reqResponse); - } - }; - let isOverlap = false; - let isNotHTMLResponse = false; - const setComment = () => { - if (isRequest) { - templateObject.response = undefined; - get?.("response", undefined); - } else { - if (dataObj.nodes) { - const parentNode = dataObj.parentNode; - if (!parentNode) createError(`${RENDER_ERROR}: ParentNode is null`); - const nodesLength = dataObj.nodes.length; - for (let i = 0; i < nodesLength; i++) { - const node = dataObj.nodes[i]; - if (i === nodesLength - 1) { - parentNode.insertBefore(dataObj.comment, node); + const reqNode = parentNode.insertBefore(node, el); + if (isRequests) { + reqResponse.push(reqNode); } - parentNode.removeChild(node); } - dataObj.nodes = null; - dataObj.parentNode = null; + parentNode.removeChild(el); if (isRequests) { - reqObject.response = undefined; - get?.("response", undefined, reqObject); + reqObject.response = reqResponse; + get?.("response", reqResponse, reqObject); } get?.("response", mainEl); } } - if (isRequestMemo) { - if (dataObj.memo.response !== null) { - dataObj.memo.response = null; - delete dataObj.memo.isPending; - delete dataObj.memo.nodes; - } + } else { + setComment(); + } + } + }).catch((error) => { + if (!isOverlap) { + updateStatusDepenencies("rejected"); + if (!indicators) { + setComment(); + } + } + throw error; + }); +}; +var getRequestInitFromFn = (fn, event) => { + const request = {}; + if (event !== void 0) { + request.event = event; + } + const context = { + request + }; + const result = fn(context); + return result; +}; +var renderTemplate = (currentEl, fn, requests, compileOptions, isMemoUndefined, isAutoBodyUndefined, isRequest = false) => { + const renderRequest = (req, mainEl) => { + const source = req.src; + if (source) { + const method = (req.method || "GET").toLowerCase(); + if (getIsMethodValid(method)) { + createError( + `${REQUEST_OBJECT_ERROR}: The "${METHOD}" property has only GET, POST, PUT, PATCH or DELETE values` + ); + } else { + const after = req.after; + if (after && isRequest) + createError(`${RENDER_ERROR}: EventTarget is undefined`); + const isModeUndefined = !req.hasOwnProperty(MODE); + if (!isModeUndefined && typeof req.repeat !== "boolean") { + createError( + `${REQUEST_OBJECT_ERROR}: The "${MODE}" property has only boolean value` + ); } - }; - const updateIndicator = (status) => { - if (indicators) { - if ( - isRequestMemo && - status !== "pending" && - getIsNotFullfilledStatus(status) - ) { - if (dataObj.memo.isPending) dataObj.memo.isPending = false; - } - if (status === "pending") { - const content = indicators["pending"]; - if (content !== undefined) { - if (isRequestMemo) { - dataObj.memo.isPending = true; - } - updateNodes(content); - } - } else if (status === "rejected") { - const content = indicators["rejected"]; - if (content !== undefined) { - updateNodes(content); - } else { - const errorContent = indicators["error"]; - if (errorContent !== undefined) { - updateNodes(errorContent); - } else { - setComment(); - } - } - } else { - const content = indicators[`${status}`]; - if (status > 399) { - isOverlap = true; - if (content !== undefined) { - updateNodes(content); + const oldMode = isModeUndefined ? true : req.repeat; + const modeAttr = oldMode ? "all" : "one"; + const isAll = modeAttr === "all"; + const isReqMemoUndefined = !req.hasOwnProperty(MEMO); + let isMemo = isMemoUndefined ? false : compileOptions.memo; + if (!isReqMemoUndefined) { + if (after) { + if (req.memo) { + if (!isAll) { + createError( + `${REQUEST_OBJECT_ERROR}: Memoization works in the enabled repetition mode` + ); } else { - const errorContent = indicators["error"]; - if (errorContent !== undefined) { - updateNodes(errorContent); - } else { - setComment(); - } + isMemo = true; } } else { - if (status < 200 || status > 299) { - isNotHTMLResponse = true; - if (content !== undefined) { - updateNodes(content); - } else { - setComment(); - } - } + isMemo = false; } - } - } - }; - const updateStatusDepenencies = (status) => { - if (isRequests) { - if (reqObject.status !== status) { - reqObject.status = status; - get?.("status", status, reqObject); + } else { + createError( + `${REQUEST_OBJECT_ERROR}: Memoization works in the enabled repetition mode` + ); } } else { - if (templateObject.status !== status) { - templateObject.status = status; - get?.("status", status); - } - } - if (isRequestMemo && getIsNotFullfilledStatus(status)) { - dataObj.memo.response = null; - delete dataObj.memo.nodes; - } - updateIndicator(status); - }; - const takeNodesFromCache = () => { - if (dataObj.memo.isPending) { - const parentNode = dataObj.parentNode; - if (!parentNode) createError(`${RENDER_ERROR}: ParentNode is null`); - const memoNodes = dataObj.memo.nodes; - const currentNodes = dataObj.nodes; - const nodesLength = currentNodes.length; - const newNodes = []; - for (let i = 0; i < nodesLength; i++) { - const node = currentNodes[i]; - if (i === nodesLength - 1) { - for (let j = 0; j < memoNodes.length; j++) { - const reqNode = memoNodes[j]; - const newNode = parentNode.insertBefore(reqNode, node); - newNodes.push(newNode); + if (isMemo) { + if (after) { + if (!isAll) { + isMemo = false; } + } else { + isMemo = false; } - parentNode.removeChild(node); } - dataObj.nodes = newNodes.slice(); - dataObj.memo.isPending = false; - dataObj.memo.nodes = newNodes.slice(); } - const reqResponse = dataObj.nodes.slice(); - callGetResponse(reqResponse); - }; - let requestStatus = 200; - updateStatusDepenencies("pending"); - fetch(source, initRequest) - .then((response) => { - requestStatus = response.status; - updateStatusDepenencies(requestStatus); - if (!response.ok) { + const isReqAutoBodyUndefined = !req.hasOwnProperty(AUTO_BODY); + let autoBody = isAutoBodyUndefined ? false : compileOptions.autoBody; + if (!isReqAutoBodyUndefined) { + if (after) { + let reqAutoBody = req[AUTO_BODY]; + validAutoBody(reqAutoBody); + if (autoBody === true) { + autoBody = DEFAULT_AUTO_BODY; + } + if (reqAutoBody === true) { + reqAutoBody = DEFAULT_AUTO_BODY; + } + if (reqAutoBody === false) { + autoBody = false; + } else { + const newAutoBody = { + ...autoBody === false ? DEFAULT_FALSE_AUTO_BODY : autoBody, + ...reqAutoBody + }; + autoBody = newAutoBody; + } + } else { + autoBody = false; createError( - `${RESPONSE_ERROR}: Response with status code ${requestStatus}` + `${REQUEST_OBJECT_ERROR}: The "${AUTO_BODY}" property does not work without the "${AFTER}" property` ); } - return response.text(); - }) - .then((data) => { - if (!isNotHTMLResponse) { - if (!getIsNotFullfilledStatus(requestStatus)) { - if (isRequestMemo) { - const { response } = dataObj.memo; - if (response === null) { - dataObj.memo.response = data; - } else { - if (response === data) { - takeNodesFromCache(); - return; - } else { - dataObj.memo.response = data; - delete dataObj.memo.nodes; - } - } - } - const templateWrapper = getResponseElements(data); - if (isRequest) { - templateObject.response = templateWrapper; - get?.("response", templateWrapper); - } else { - const reqResponse = []; - const nodes = templateWrapper.content.childNodes; - if (dataObj) { - updateNodes(templateWrapper, false, true); - } else { - const parentNode = el.parentNode; - for (let i = 0; i < nodes.length; i++) { - const node = nodes[i]; - const reqNode = parentNode.insertBefore(node, el); - if (isRequests) { - reqResponse.push(reqNode); - } - } - parentNode.removeChild(el); - if (isRequests) { - reqObject.response = reqResponse; - get?.("response", reqResponse, reqObject); - } - get?.("response", mainEl); - } - } - } else { - setComment(); - } + } else { + if (autoBody === true) { + autoBody = DEFAULT_AUTO_BODY; } - }) - .catch((error) => { - if (!isOverlap) { - updateStatusDepenencies("rejected"); - if (!indicators) { - setComment(); - } + if (!after) { + autoBody = false; } - throw error; - }); - }; - const getRequestInitFromFn = (fn, event) => { - const request = {}; - if (event !== undefined) { - request.event = event; - } - const context = { - request - }; - const result = fn(context); - return result; - }; - const renderTemplate = ( - currentEl, - fn, - requests, - compileOptions, - isMemoUndefined, - isAutoBodyUndefined, - isRequest = false - ) => { - const renderRequest = (req, mainEl) => { - const source = req.src; - if (source) { - const method = (req.method || "GET").toLowerCase(); - if (getIsMethodValid(method)) { - createError( - `${REQUEST_OBJECT_ERROR}: The "${METHOD}" property has only GET, POST, PUT, PATCH or DELETE values` + } + const initId = req.initId; + const nodeId = req.nodeId; + let indicators = req.indicators; + if (indicators) { + const parseIndicator = (val) => { + const { trigger, content } = val; + if (!trigger) + createError( + `${REQUEST_OBJECT_ERROR}: Failed to activate or detect the indicator` + ); + if (!content) + createError( + `${REQUEST_OBJECT_ERROR}: Failed to activate or detect the indicator` + ); + if (codes.indexOf(trigger) === -1 && trigger !== "pending" && trigger !== "rejected" && trigger !== "error") { + createError( + `${REQUEST_OBJECT_ERROR}: Failed to activate or detect the indicator` + ); + } + const elWrapper = getTemplateWrapper( + content ); - } else { - const after = req.after; - if (after && isRequest) - createError(`${RENDER_ERROR}: EventTarget is undefined`); - const isModeUndefined = !req.hasOwnProperty(MODE); - if (!isModeUndefined && typeof req.repeat !== "boolean") { + return { + ...val, + content: elWrapper + }; + }; + const newOn = {}; + const uniqueTriggers = []; + for (let i = 0; i < indicators.length; i++) { + const currentIndicator = parseIndicator(indicators[i]); + const { trigger } = currentIndicator; + if (uniqueTriggers.indexOf(trigger) === -1) { + uniqueTriggers.push(trigger); + } else { createError( - `${REQUEST_OBJECT_ERROR}: The "${MODE}" property has only boolean value` + `${REQUEST_OBJECT_ERROR}: Indicator trigger must be unique` ); } - const oldMode = isModeUndefined ? true : req.repeat; - const modeAttr = oldMode ? "all" : "one"; - const isAll = modeAttr === "all"; - const isReqMemoUndefined = !req.hasOwnProperty(MEMO); - let isMemo = isMemoUndefined ? false : compileOptions.memo; - if (!isReqMemoUndefined) { - if (after) { - if (req.memo) { - if (!isAll) { - createError( - `${REQUEST_OBJECT_ERROR}: Memoization works in the enabled repetition mode` - ); - } else { - isMemo = true; - } - } else { - isMemo = false; + newOn[`${trigger}`] = currentIndicator.content; + } + indicators = newOn; + } + const getOptions = (options, isArray = false) => { + if (isArray) { + if (initId) { + let result; + for (let i = 0; i < options.length; i++) { + const currentOptions = options[i]; + if (currentOptions.id === initId) { + result = currentOptions.value; + break; } - } else { + } + if (!result) { createError( - `${REQUEST_OBJECT_ERROR}: Memoization works in the enabled repetition mode` + `${REQUEST_OBJECT_ERROR}: ID referenced by request not found` ); } + return result; } else { - if (isMemo) { - if (after) { - if (!isAll) { - isMemo = false; - } - } else { - isMemo = false; - } - } + return {}; } - const isReqAutoBodyUndefined = !req.hasOwnProperty(AUTO_BODY); - let autoBody = isAutoBodyUndefined - ? false - : compileOptions.autoBody; - if (!isReqAutoBodyUndefined) { - if (after) { - let reqAutoBody = req[AUTO_BODY]; - validAutoBody(reqAutoBody); - if (autoBody === true) { - autoBody = DEFAULT_AUTO_BODY; - } - if (reqAutoBody === true) { - reqAutoBody = DEFAULT_AUTO_BODY; - } - if (reqAutoBody === false) { - autoBody = false; - } else { - const newAutoBody = { - ...(autoBody === false - ? DEFAULT_FALSE_AUTO_BODY - : autoBody), - ...reqAutoBody - }; - autoBody = newAutoBody; - } + } else { + if (initId) + createError( + `${REQUEST_OBJECT_ERROR}: ID referenced by request not found` + ); + return options; + } + }; + const isDataObj = isAll && after; + const reqFunction = (reqEl, options, templateObject, data, reqMainEl, isArray = false, reqObject, isRequests = false, currentHMPLElement, event) => { + const id = data.currentId; + if (isRequest) { + if (!reqEl) reqEl = mainEl; + } else { + if (!reqEl) { + if (currentHMPLElement) { + reqEl = currentHMPLElement.el; } else { - autoBody = false; - } - } else { - if (autoBody === true) { - autoBody = DEFAULT_AUTO_BODY; - } - if (!after) { - autoBody = false; - } - } - const initId = req.initId; - const nodeId = req.nodeId; - let indicators = req.indicators; - if (indicators) { - const parseIndicator = (val) => { - const { trigger, content } = val; - if (!trigger) - createError( - `${REQUEST_OBJECT_ERROR}: Failed to activate or detect the indicator` - ); - if (!content) - createError( - `${REQUEST_OBJECT_ERROR}: Failed to activate or detect the indicator` - ); - if ( - codes.indexOf(trigger) === -1 && - trigger !== "pending" && - trigger !== "rejected" && - trigger !== "error" - ) { - createError( - `${REQUEST_OBJECT_ERROR}: Failed to activate or detect the indicator` - ); - } - const elWrapper = getTemplateWrapper(content); - return { - ...val, - content: elWrapper - }; - }; - const newOn = {}; - const uniqueTriggers = []; - for (let i = 0; i < indicators.length; i++) { - const currentIndicator = parseIndicator(indicators[i]); - const { trigger } = currentIndicator; - if (uniqueTriggers.indexOf(trigger) === -1) { - uniqueTriggers.push(trigger); - } else { - createError( - `${REQUEST_OBJECT_ERROR}: Indicator trigger must be unique` - ); - } - newOn[`${trigger}`] = currentIndicator.content; - } - indicators = newOn; - } - const getOptions = (options, isArray = false) => { - if (isArray) { - if (initId) { - let result; - for (let i = 0; i < options.length; i++) { - const currentOptions = options[i]; - if (currentOptions.id === initId) { - result = currentOptions.value; - break; - } - } - if (!result) { - createError( - `${REQUEST_OBJECT_ERROR}: ID referenced by request not found` - ); + let currentEl2; + const { els } = data; + for (let i = 0; i < els.length; i++) { + const e = els[i]; + if (e.id === nodeId) { + currentHMPLElement = e; + currentEl2 = e.el; + break; } - return result; - } else { - return {}; } - } else { - if (initId) + if (!currentEl2) { createError( - `${REQUEST_OBJECT_ERROR}: ID referenced by request not found` + `${RENDER_ERROR}: The specified DOM element is not valid or cannot be found` ); - return options; - } - }; - const isDataObj = isAll && after; - const reqFunction = ( - reqEl, - options, - templateObject, - data, - reqMainEl, - isArray = false, - reqObject, - isRequests = false, - currentHMPLElement, - event - ) => { - const id = data.currentId; - if (isRequest) { - if (!reqEl) reqEl = mainEl; - } else { - if (!reqEl) { - if (currentHMPLElement) { - reqEl = currentHMPLElement.el; - } else { - let currentEl; - const { els } = data; - for (let i = 0; i < els.length; i++) { - const e = els[i]; - if (e.id === nodeId) { - currentHMPLElement = e; - currentEl = e.el; - break; - } - } - if (!currentEl) { - createError( - `${RENDER_ERROR}: The specified DOM element is not valid or cannot be found` - ); - } - reqEl = currentEl; - } } + reqEl = currentEl2; } - let dataObj; - if (!isRequest) { - if (isDataObj || indicators) { - if (!currentHMPLElement) - createError( - `${RENDER_ERROR}: The specified DOM element is not valid or cannot be found` - ); - dataObj = currentHMPLElement.objNode; - if (!dataObj) { - dataObj = { - id, - nodes: null, - parentNode: null, - comment: reqEl - }; - if (isMemo) { - dataObj.memo = { - response: null - }; - if (indicators) { - dataObj.memo.isPending = false; - } - } - currentHMPLElement.objNode = dataObj; - data.dataObjects.push(dataObj); - data.currentId++; + } + } + let dataObj; + if (!isRequest) { + if (isDataObj || indicators) { + if (!currentHMPLElement) + createError( + `${RENDER_ERROR}: The specified DOM element is not valid or cannot be found` + ); + dataObj = currentHMPLElement.objNode; + if (!dataObj) { + dataObj = { + id, + nodes: null, + parentNode: null, + comment: reqEl + }; + if (isMemo) { + dataObj.memo = { + response: null + }; + if (indicators) { + dataObj.memo.isPending = false; } } + currentHMPLElement.objNode = dataObj; + data.dataObjects.push(dataObj); + data.currentId++; } - let currentOptions = getOptions(options, isArray); - const isOptionsFunction = checkFunction(currentOptions); - if (!isOptionsFunction && currentOptions) - currentOptions = { ...currentOptions }; - if ( - autoBody && - autoBody.formData && - event && - !isOptionsFunction - ) { - const { type, target } = event; - if ( - type === "submit" && - target && - target instanceof HTMLFormElement && - target.nodeName === "FORM" - ) { - currentOptions.body = new FormData(target, event.submitter); - } - } - const requestInit = isOptionsFunction - ? getRequestInitFromFn(currentOptions, event) - : currentOptions; - if (!checkObject(requestInit) && requestInit !== undefined) - createError( - `${REQUEST_INIT_ERROR}: Expected an object with initialization options` - ); - makeRequest( + } + } + let currentOptions = getOptions(options, isArray); + const isOptionsFunction = checkFunction(currentOptions); + if (!isOptionsFunction && currentOptions) + currentOptions = { ...currentOptions }; + if (autoBody && autoBody.formData && event && !isOptionsFunction) { + const { type, target } = event; + if (type === "submit" && target && target instanceof HTMLFormElement && target.nodeName === "FORM") { + currentOptions.body = new FormData( + target, + event.submitter + ); + } + } + const requestInit = isOptionsFunction ? getRequestInitFromFn( + currentOptions, + event + ) : currentOptions; + if (!checkObject(requestInit) && requestInit !== void 0) + createError( + `${REQUEST_INIT_ERROR}: Expected an object with initialization options` + ); + makeRequest( + reqEl, + reqMainEl, + dataObj, + method, + source, + isRequest, + isRequests, + isMemo, + requestInit, + templateObject, + reqObject, + indicators + ); + }; + let requestFunction = reqFunction; + if (after) { + const setEvents = (reqEl, event, selector, options, templateObject, data, isArray, isRequests, reqMainEl, reqObject, currentHMPLElement) => { + const els = reqMainEl.querySelectorAll(selector); + if (els.length === 0) { + createError(`${RENDER_ERROR}: Selectors nodes not found`); + } + const afterFn = isAll ? (evt) => { + reqFunction( reqEl, + options, + templateObject, + data, reqMainEl, - dataObj, - method, - source, - isRequest, + isArray, + reqObject, isRequests, - isMemo, - requestInit, + currentHMPLElement, + evt + ); + } : (evt) => { + reqFunction( + reqEl, + options, templateObject, + data, + reqMainEl, + isArray, reqObject, - indicators + isRequests, + currentHMPLElement, + evt ); + for (let j = 0; j < els.length; j++) { + const currentAfterEl = els[j]; + currentAfterEl.removeEventListener(event, afterFn); + } }; - let requestFunction = reqFunction; - if (after) { - const setEvents = ( + for (let i = 0; i < els.length; i++) { + const afterEl = els[i]; + afterEl.addEventListener(event, afterFn); + } + }; + if (after.indexOf(":") > 0) { + const afterArr = after.split(":"); + const event = afterArr[0]; + const selector = afterArr.slice(1).join(":"); + requestFunction = (reqEl, options, templateObject, data, reqMainEl, isArray = false, reqObject, isRequests = false, currentHMPLElement) => { + setEvents( reqEl, event, selector, @@ -769,567 +824,485 @@ reqMainEl, reqObject, currentHMPLElement - ) => { - const els = reqMainEl.querySelectorAll(selector); - if (els.length === 0) { - createError(`${RENDER_ERROR}: Selectors nodes not found`); - } - const afterFn = isAll - ? (evt) => { - reqFunction( - reqEl, - options, - templateObject, - data, - reqMainEl, - isArray, - reqObject, - isRequests, - currentHMPLElement, - evt - ); - } - : (evt) => { - reqFunction( - reqEl, - options, - templateObject, - data, - reqMainEl, - isArray, - reqObject, - isRequests, - currentHMPLElement, - evt - ); - for (let j = 0; j < els.length; j++) { - const currentAfterEl = els[j]; - currentAfterEl.removeEventListener(event, afterFn); - } - }; - for (let i = 0; i < els.length; i++) { - const afterEl = els[i]; - afterEl.addEventListener(event, afterFn); - } - }; - if (after.indexOf(":") > 0) { - const afterArr = after.split(":"); - const event = afterArr[0]; - const selector = afterArr.slice(1).join(":"); - requestFunction = ( - reqEl, - options, - templateObject, - data, - reqMainEl, - isArray = false, - reqObject, - isRequests = false, - currentHMPLElement - ) => { - setEvents( - reqEl, - event, - selector, - options, - templateObject, - data, - isArray, - isRequests, - reqMainEl, - reqObject, - currentHMPLElement - ); - }; - } else { - createError( - `${REQUEST_OBJECT_ERROR}: The "${AFTER}" property doesn't work without EventTargets` - ); - } - } else { - if (!isModeUndefined) { - createError( - `${REQUEST_OBJECT_ERROR}: The "${MODE}" property doesn't work without "${AFTER}" property` - ); - } - } - return requestFunction; + ); + }; + } else { + createError( + `${REQUEST_OBJECT_ERROR}: The "${AFTER}" property doesn't work without EventTargets` + ); } } else { - createError( - `${REQUEST_OBJECT_ERROR}: The "source" property are not found or empty` - ); - } - }; - let reqFn; - if (isRequest) { - requests[0].el = currentEl; - reqFn = renderRequest(requests[0]); - } else { - let id = -2; - const getRequests = (currrentElement) => { - id++; - if (currrentElement.nodeType == 8) { - let value = currrentElement.nodeValue; - if (value && value.startsWith(COMMENT)) { - value = value.slice(4); - const currentIndex = Number(value); - const currentRequest = requests[currentIndex]; - if (Number.isNaN(currentIndex) || currentRequest === undefined) { - createError(`${RENDER_ERROR}: Request object not found`); - } - currentRequest.el = currrentElement; - currentRequest.nodeId = id; - } - } - if (currrentElement.hasChildNodes()) { - const chNodes = currrentElement.childNodes; - for (let i = 0; i < chNodes.length; i++) { - getRequests(chNodes[i]); - } + if (!isModeUndefined) { + createError( + `${REQUEST_OBJECT_ERROR}: The "${MODE}" property doesn't work without "${AFTER}" property` + ); } - }; - getRequests(currentEl); - const algorithm = []; - for (let i = 0; i < requests.length; i++) { - const currentRequest = requests[i]; - algorithm.push(renderRequest(currentRequest, currentEl)); } - if (requests.length > 1) { - reqFn = ( - reqEl, - options, - templateObject, - data, - mainEl, - isArray = false - ) => { - if (!reqEl) { - reqEl = mainEl; - } - const requests = []; - const els = data.els; - for (let i = 0; i < els.length; i++) { - const hmplElement = els[i]; - const currentReqEl = hmplElement.el; - if (currentReqEl.parentNode === null) { - createError(`${RENDER_ERROR}: ParentNode is null`); - } - const currentReqFn = algorithm[i]; - const currentReq = { - response: undefined - }; - currentReqFn( - currentReqEl, - options, - templateObject, - data, - reqEl, - isArray, - currentReq, - true, - hmplElement - ); - requests.push(currentReq); - } - templateObject.requests = requests; - }; - } else { - const currentRequest = requests[0]; - if (currentRequest.el.parentNode === null) { - createError(`${RENDER_ERROR}: ParentNode is null`); + return requestFunction; + } + } else { + createError( + `${REQUEST_OBJECT_ERROR}: The "source" property are not found or empty` + ); + } + }; + let reqFn; + if (isRequest) { + requests[0].el = currentEl; + reqFn = renderRequest(requests[0]); + } else { + let id = -2; + const getRequests = (currrentElement) => { + id++; + if (currrentElement.nodeType == 8) { + let value = currrentElement.nodeValue; + if (value && value.startsWith(COMMENT)) { + value = value.slice(4); + const currentIndex = Number(value); + const currentRequest = requests[currentIndex]; + if (Number.isNaN(currentIndex) || currentRequest === void 0) { + createError(`${RENDER_ERROR}: Request object not found`); } - reqFn = renderRequest(currentRequest, currentEl); + currentRequest.el = currrentElement; + currentRequest.nodeId = id; } } - return fn(reqFn); - }; - const validOptions = (currentOptions) => { - const isObject = checkObject(currentOptions); - if ( - !isObject && - !checkFunction(currentOptions) && - currentOptions !== undefined - ) - createError( - `${REQUEST_INIT_ERROR}: Expected an object with initialization options` - ); - if (isObject && currentOptions.get) { - if (!checkFunction(currentOptions.get)) { - createError( - `${REQUEST_INIT_ERROR}: The "get" property has a function value` - ); + if (currrentElement.hasChildNodes()) { + const chNodes = currrentElement.childNodes; + for (let i = 0; i < chNodes.length; i++) { + getRequests(chNodes[i]); } } }; - const validAutoBody = (autoBody) => { - const isObject = checkObject(autoBody); - if (typeof autoBody !== "boolean" && !isObject) - createError( - `${REQUEST_OBJECT_ERROR}: Expected a boolean or object, but got neither` - ); - if (isObject) { - for (const key in autoBody) { - switch (key) { - case FORM_DATA: - if (typeof autoBody[FORM_DATA] !== "boolean") - createError( - `${REQUEST_OBJECT_ERROR}: The "${FORM_DATA}" property should be a boolean` - ); - break; - default: - createError( - `${REQUEST_OBJECT_ERROR}: Unexpected property "${key}"` - ); - break; - } + getRequests(currentEl); + const algorithm = []; + for (let i = 0; i < requests.length; i++) { + const currentRequest = requests[i]; + algorithm.push(renderRequest(currentRequest, currentEl)); + } + if (requests.length > 1) { + reqFn = (reqEl, options, templateObject, data, mainEl, isArray = false) => { + if (!reqEl) { + reqEl = mainEl; } - } - }; - const validIdOptions = (currentOptions) => { - if (checkObject(currentOptions)) { - if ( - !currentOptions.hasOwnProperty("id") || - !currentOptions.hasOwnProperty("value") - ) { - createError( - `${REQUEST_OBJECT_ERROR}: Missing "id" or "value" property` + const requests2 = []; + const els = data.els; + for (let i = 0; i < els.length; i++) { + const hmplElement = els[i]; + const currentReqEl = hmplElement.el; + if (currentReqEl.parentNode === null) { + createError(`${RENDER_ERROR}: ParentNode is null`); + } + const currentReqFn = algorithm[i]; + const currentReq = { + response: void 0 + }; + currentReqFn( + currentReqEl, + options, + templateObject, + data, + reqEl, + isArray, + currentReq, + true, + hmplElement ); + requests2.push(currentReq); } - } else { - createError( - `${REQUEST_OBJECT_ERROR}: IdentificationRequestInit must be of type object` - ); + templateObject.requests = requests2; + }; + } else { + const currentRequest = requests[0]; + if (currentRequest.el.parentNode === null) { + createError(`${RENDER_ERROR}: ParentNode is null`); } - }; - const validIdentificationOptionsArray = (currentOptions) => { - const ids = []; - for (let i = 0; i < currentOptions.length; i++) { - const idOptions = currentOptions[i]; - if (!checkObject(idOptions)) - createError(`${REQUEST_OBJECT_ERROR}: Options is of type object`); - validIdOptions(idOptions); - const { id } = idOptions; - if ( - typeof idOptions.id !== "string" && - typeof idOptions.id !== "number" - ) - createError( - `${REQUEST_OBJECT_ERROR}: ID must be a string or a number` - ); - if (ids.indexOf(id) > -1) { - createError( - `${REQUEST_OBJECT_ERROR}: ID with value "${id}" already exists` - ); - } else { - ids.push(id); - } + reqFn = renderRequest(currentRequest, currentEl); + } + } + return fn(reqFn); +}; +var validOptions = (currentOptions) => { + const isObject = checkObject(currentOptions); + if (!isObject && !checkFunction(currentOptions) && currentOptions !== void 0) + createError( + `${REQUEST_INIT_ERROR}: Expected an object with initialization options` + ); + if (isObject && currentOptions.get) { + if (!checkFunction(currentOptions.get)) { + createError( + `${REQUEST_INIT_ERROR}: The "get" property has a function value` + ); + } + } +}; +var validAutoBody = (autoBody) => { + const isObject = checkObject(autoBody); + if (typeof autoBody !== "boolean" && !isObject) + createError( + `${REQUEST_OBJECT_ERROR}: Expected a boolean or object, but got neither` + ); + if (isObject) { + for (const key in autoBody) { + switch (key) { + case FORM_DATA: + if (typeof autoBody[FORM_DATA] !== "boolean") + createError( + `${REQUEST_OBJECT_ERROR}: The "${FORM_DATA}" property should be a boolean` + ); + break; + default: + createError(`${REQUEST_OBJECT_ERROR}: Unexpected property "${key}"`); + break; } - }; - const stringify = (info) => { - return JSON.stringify(info); - }; - const compile = (template, options = {}) => { - if (typeof template !== "string") - createError( - `${COMPILE_ERROR}: Template was not found or the type of the passed value is not string` - ); - if (!template) - createError(`${COMPILE_ERROR}: Template must not be a falsey value`); - if (!checkObject(options)) - createError(`${COMPILE_ERROR}: Options must be an object`); - const isMemoUndefined = !options.hasOwnProperty(MEMO); - if (!isMemoUndefined && typeof options[MEMO] !== "boolean") + } + } +}; +var validIdOptions = (currentOptions) => { + if (checkObject(currentOptions)) { + if (!currentOptions.hasOwnProperty("id") || !currentOptions.hasOwnProperty("value")) { + createError(`${REQUEST_OBJECT_ERROR}: Missing "id" or "value" property`); + } + } else { + createError( + `${REQUEST_OBJECT_ERROR}: IdentificationRequestInit must be of type object` + ); + } +}; +var validIdentificationOptionsArray = (currentOptions) => { + const ids = []; + for (let i = 0; i < currentOptions.length; i++) { + const idOptions = currentOptions[i]; + if (!checkObject(idOptions)) + createError(`${REQUEST_OBJECT_ERROR}: Options is of type object`); + validIdOptions(idOptions); + const { id } = idOptions; + if (typeof idOptions.id !== "string" && typeof idOptions.id !== "number") + createError(`${REQUEST_OBJECT_ERROR}: ID must be a string or a number`); + if (ids.indexOf(id) > -1) { + createError( + `${REQUEST_OBJECT_ERROR}: ID with value "${id}" already exists` + ); + } else { + ids.push(id); + } + } +}; +var stringify = (info) => { + return import_json5.default.stringify(info); +}; +var compile = (template, options = {}) => { + if (typeof template !== "string") + createError( + `${COMPILE_ERROR}: Template was not found or the type of the passed value is not string` + ); + if (!template) + createError(`${COMPILE_ERROR}: Template must not be a falsey value`); + if (!checkObject(options)) + createError(`${COMPILE_ERROR}: Options must be an object`); + const isMemoUndefined = !options.hasOwnProperty(MEMO); + if (!isMemoUndefined && typeof options[MEMO] !== "boolean") + createError( + `${REQUEST_OBJECT_ERROR}: The value of the property ${MEMO} must be a boolean value` + ); + const isAutoBodyUndefined = !options.hasOwnProperty(AUTO_BODY); + if (!isAutoBodyUndefined) validAutoBody(options[AUTO_BODY]); + const requests = []; + const templateArr = template.split(MAIN_REGEX).filter(Boolean); + const requestsIndexes = []; + for (const match of template.matchAll(MAIN_REGEX)) { + requestsIndexes.push(match.index); + } + if (requestsIndexes.length === 0) + createError(`${PARSE_ERROR}: Request not found`); + const prepareText = (text) => { + text = text.trim(); + text = text.replace(/\r?\n|\r/g, ""); + return text; + }; + const setRequest = (text, i) => { + const parsedData = import_json5.default.parse(text); + for (const key in parsedData) { + const value = parsedData[key]; + if (!requestOptions.includes(key)) createError( - `${REQUEST_OBJECT_ERROR}: The value of the property ${MEMO} must be a boolean value` + `${REQUEST_OBJECT_ERROR}: Property "${key}" is not processed` ); - const isAutoBodyUndefined = !options.hasOwnProperty(AUTO_BODY); - if (!isAutoBodyUndefined) validAutoBody(options[AUTO_BODY]); - const requests = []; - const templateArr = template.split(MAIN_REGEX).filter(Boolean); - const requestsIndexes = []; - for (const match of template.matchAll(MAIN_REGEX)) { - requestsIndexes.push(match.index); - } - if (requestsIndexes.length === 0) - createError(`${PARSE_ERROR}: Request not found`); - const prepareText = (text) => { - text = text.trim(); - text = text.replace(/\r?\n|\r/g, ""); - return text; - }; - const setRequest = (text, i) => { - const parsedData = JSON.parse(text); - for (const key in parsedData) { - const value = parsedData[key]; - if (!requestOptions.includes(key)) + switch (key) { + case INDICATORS: + if (!Array.isArray(value)) { createError( - `${REQUEST_OBJECT_ERROR}: Property "${key}" is not processed` + `${REQUEST_OBJECT_ERROR}: The value of the property "${key}" must be an array` ); - switch (key) { - case INDICATORS: - if (!Array.isArray(value)) { - createError( - `${REQUEST_OBJECT_ERROR}: The value of the property "${key}" must be an array` - ); - } - break; - case ID: - if (typeof value !== "string" && typeof value !== "number") { - createError( - `${REQUEST_OBJECT_ERROR}: The value of the property "${key}" must be a string` - ); - } - break; - case MEMO: - case MODE: - if (typeof value !== "boolean") { - createError( - `${REQUEST_OBJECT_ERROR}: The value of the property "${key}" must be a boolean value` - ); - } - break; - case AUTO_BODY: - validAutoBody(value); - break; - default: - if (typeof value !== "string") { - createError( - `${REQUEST_OBJECT_ERROR}: The value of the property "${key}" must be a string` - ); - } - break; } - } - const requestObject = { - ...parsedData, - arrId: i - }; - requests.push(requestObject); - }; - let stringIndex = 0; - for (let i = 0; i < templateArr.length; i++) { - const text = templateArr[i]; - if (requestsIndexes.includes(stringIndex)) { - const requestObjectArr = text.split(BRACKET_REGEX).filter(Boolean); - let currentBracketId = -1; - let newText = ""; - let isFirst = true; - let isFinal = false; - for (let j = 0; j < requestObjectArr.length; j++) { - const requestText = requestObjectArr[j]; - const isOpen = requestText === "{"; - const isClose = requestText === "}"; - if (isOpen) { - if (isFirst) { - isFirst = false; - if (requestObjectArr[j + 1] !== "{") j++; - } else { - newText += requestText; - } - currentBracketId++; - } else if (isClose) { - if (currentBracketId === -1) { - createError( - `${PARSE_ERROR}: Handling curly braces in the Request Object` - ); - } - if (currentBracketId === 1) { - isFinal = true; - } - if (currentBracketId === 0) { - setRequest(newText, i); - currentBracketId--; - stringIndex += text.length; - break; - } - currentBracketId--; - newText += requestText; - } else { - if (isFinal) { - if (prepareText(requestText)) { - createError( - `${PARSE_ERROR}: There is no empty space between the curly brackets` - ); - } - } else { - newText += requestText; - } - } + break; + case ID: + if (typeof value !== "string" && typeof value !== "number") { + createError( + `${REQUEST_OBJECT_ERROR}: The value of the property "${key}" must be a string` + ); } - if (currentBracketId !== -1) { - const nextId = i + 1; - const nextText = templateArr[nextId]; - if (nextText === undefined) { - createError( - `${PARSE_ERROR}: Handling curly braces in the Request Object` - ); - } - const nextArr = nextText.split(BRACKET_REGEX).filter(Boolean); - let newNextText = ""; - for (let j = 0; j < nextArr.length; j++) { - const currentNextText = nextArr[j]; - const isOpen = currentNextText === "{"; - const isClose = currentNextText === "}"; - if (isClose) { - if (currentBracketId === -1) { - createError( - `${PARSE_ERROR}: Handling curly braces in the Request Object` - ); - } - if (currentBracketId === 1) { - isFinal = true; - } - if (currentBracketId === 0) { - const newNextArr = [...nextArr]; - stringIndex += text.length + nextText.length; - newNextArr.splice(0, j + 1); - templateArr[nextId] = newNextArr.join(""); - setRequest(newText + newNextText, i); - currentBracketId--; - i++; - break; - } - currentBracketId--; - newNextText += currentNextText; - } else if (isOpen) { - newNextText += currentNextText; - currentBracketId++; - } else { - if (isFinal) { - if (prepareText(currentNextText)) { - createError( - `${PARSE_ERROR}: There is no empty space between the curly brackets` - ); - } - } else { - newNextText += currentNextText; - } - } - } + break; + case MEMO: + case MODE: + if (typeof value !== "boolean") { + createError( + `${REQUEST_OBJECT_ERROR}: The value of the property "${key}" must be a boolean value` + ); + } + break; + case AUTO_BODY: + validAutoBody(value); + break; + default: + if (typeof value !== "string") { + createError( + `${REQUEST_OBJECT_ERROR}: The value of the property "${key}" must be a string` + ); + } + break; + } + } + const requestObject = { + ...parsedData, + arrId: i + }; + requests.push(requestObject); + }; + let stringIndex = 0; + for (let i = 0; i < templateArr.length; i++) { + const text = templateArr[i]; + if (requestsIndexes.includes(stringIndex)) { + const requestObjectArr = text.split(BRACKET_REGEX).filter(Boolean); + let currentBracketId = -1; + let newText = ""; + let isFirst = true; + let isFinal = false; + for (let j = 0; j < requestObjectArr.length; j++) { + const requestText = requestObjectArr[j]; + const isOpen = requestText === "{"; + const isClose = requestText === "}"; + if (isOpen) { + if (isFirst) { + isFirst = false; + if (requestObjectArr[j + 1] !== "{") j++; + } else { + newText += requestText; } - if (currentBracketId !== -1) { + currentBracketId++; + } else if (isClose) { + if (currentBracketId === -1) { createError( `${PARSE_ERROR}: Handling curly braces in the Request Object` ); } + if (currentBracketId === 1) { + isFinal = true; + } + if (currentBracketId === 0) { + setRequest(newText, i); + currentBracketId--; + stringIndex += text.length; + break; + } + currentBracketId--; + newText += requestText; } else { - stringIndex += text.length; + if (isFinal) { + if (prepareText(requestText)) { + createError( + `${PARSE_ERROR}: There is no empty space between the curly brackets` + ); + } + } else { + newText += requestText; + } } } - if (requests.length === 0) { - createError(`${PARSE_ERROR}: Request not found`); - } - for (let i = 0; i < requests.length; i++) { - const request = requests[i]; - const { arrId } = request; - const comment = ``; - templateArr[arrId] = comment; - delete request.arrId; - } - template = templateArr.join(""); - let isRequest = false; - const getElement = (template) => { - const elWrapper = getTemplateWrapper(template.trim()); - if ( - elWrapper.content.childNodes.length > 1 || - elWrapper.content.children.length !== 1 - ) { + if (currentBracketId !== -1) { + const nextId = i + 1; + const nextText = templateArr[nextId]; + if (nextText === void 0) { createError( - `${RENDER_ERROR}: Template include only one node with type Element or Comment` + `${PARSE_ERROR}: Handling curly braces in the Request Object` ); } - const prepareNode = (node) => { - switch (node.nodeType) { - case Node.ELEMENT_NODE: - if (node.tagName === "pre") return; - break; - case Node.TEXT_NODE: - if (!/\S/.test(node.textContent)) { - node.remove(); - return; - } + const nextArr = nextText.split(BRACKET_REGEX).filter(Boolean); + let newNextText = ""; + for (let j = 0; j < nextArr.length; j++) { + const currentNextText = nextArr[j]; + const isOpen = currentNextText === "{"; + const isClose = currentNextText === "}"; + if (isClose) { + if (currentBracketId === -1) { + createError( + `${PARSE_ERROR}: Handling curly braces in the Request Object` + ); + } + if (currentBracketId === 1) { + isFinal = true; + } + if (currentBracketId === 0) { + const newNextArr = [...nextArr]; + stringIndex += text.length + nextText.length; + newNextArr.splice(0, j + 1); + templateArr[nextId] = newNextArr.join(""); + setRequest(newText + newNextText, i); + currentBracketId--; + i++; break; - } - for (let i = 0; i < node.childNodes.length; i++) { - prepareNode(node.childNodes.item(i)); - } - }; - prepareNode(elWrapper.content.childNodes[0]); - let currentEl = elWrapper.content.firstElementChild; - if (!currentEl) { - const comment = elWrapper.content.firstChild; - const isComment = comment?.nodeType === 8; - if (isComment) { - isRequest = isComment; - currentEl = comment; + } + currentBracketId--; + newNextText += currentNextText; + } else if (isOpen) { + newNextText += currentNextText; + currentBracketId++; } else { - createError(`${RENDER_ERROR}: Element is undefined`); + if (isFinal) { + if (prepareText(currentNextText)) { + createError( + `${PARSE_ERROR}: There is no empty space between the curly brackets` + ); + } + } else { + newNextText += currentNextText; + } } } - return currentEl; + } + if (currentBracketId !== -1) { + createError( + `${PARSE_ERROR}: Handling curly braces in the Request Object` + ); + } + } else { + stringIndex += text.length; + } + } + if (requests.length === 0) { + createError(`${PARSE_ERROR}: Request not found`); + } + for (let i = 0; i < requests.length; i++) { + const request = requests[i]; + const { arrId } = request; + const comment = ``; + templateArr[arrId] = comment; + delete request.arrId; + } + template = templateArr.join(""); + let isRequest = false; + const getElement = (template2) => { + const elWrapper = getTemplateWrapper( + template2.trim() + ); + if (elWrapper.content.childNodes.length > 1 || elWrapper.content.children.length !== 1 && elWrapper.content.childNodes[0].nodeType !== 8) { + createError( + `${RENDER_ERROR}: Template include only one node with type Element or Comment` + ); + } + const prepareNode = (node) => { + switch (node.nodeType) { + case Node.ELEMENT_NODE: + if (node.tagName === "pre") return; + break; + case Node.TEXT_NODE: + if (!/\S/.test(node.textContent)) { + node.remove(); + return; + } + break; + } + for (let i = 0; i < node.childNodes.length; i++) { + prepareNode(node.childNodes.item(i)); + } + }; + prepareNode(elWrapper.content.childNodes[0]); + let currentEl = elWrapper.content.firstElementChild; + if (!currentEl) { + const comment = elWrapper.content.firstChild; + const isComment = comment?.nodeType === 8; + if (isComment) { + isRequest = isComment; + currentEl = comment; + } else { + createError(`${RENDER_ERROR}: Element is undefined`); + } + } + return currentEl; + }; + const templateEl = getElement(template); + const renderFn = (requestFunction) => { + const templateFunction = (options2 = {}) => { + const el = templateEl.cloneNode(true); + const templateObject = { + response: isRequest ? void 0 : el }; - const templateEl = getElement(template); - const renderFn = (requestFunction) => { - const templateFunction = (options = {}) => { - const el = templateEl.cloneNode(true); - const templateObject = { - response: isRequest ? undefined : el - }; - const data = { - dataObjects: [], - els: [], - currentId: 0 - }; - if (!isRequest) { - let id = -2; - const getRequests = (currrentElement) => { - id++; - if (currrentElement.nodeType == 8) { - const value = currrentElement.nodeValue; - if (value && value.startsWith(COMMENT)) { - const elObj = { - el: currrentElement, - id - }; - data.els.push(elObj); - } - } - if (currrentElement.hasChildNodes()) { - const chNodes = currrentElement.childNodes; - for (let i = 0; i < chNodes.length; i++) { - getRequests(chNodes[i]); - } - } - }; - getRequests(el); + const data = { + dataObjects: [], + els: [], + currentId: 0 + }; + if (!isRequest) { + let id = -2; + const getRequests = (currrentElement) => { + id++; + if (currrentElement.nodeType == 8) { + const value = currrentElement.nodeValue; + if (value && value.startsWith(COMMENT)) { + const elObj = { + el: currrentElement, + id + }; + data.els.push(elObj); + } } - if (checkObject(options) || checkFunction(options)) { - validOptions(options); - requestFunction(undefined, options, templateObject, data, el); - } else if (Array.isArray(options)) { - validIdentificationOptionsArray(options); - requestFunction(undefined, options, templateObject, data, el, true); + if (currrentElement.hasChildNodes()) { + const chNodes = currrentElement.childNodes; + for (let i = 0; i < chNodes.length; i++) { + getRequests(chNodes[i]); + } } - return templateObject; }; - return templateFunction; - }; - return renderTemplate( - templateEl, - renderFn, - requests, - options, - isMemoUndefined, - isAutoBodyUndefined, - isRequest - ); - }; - - const hmpl = { - compile, - stringify + getRequests(el); + } + if (checkObject(options2) || checkFunction(options2)) { + validOptions(options2); + requestFunction( + void 0, + options2, + templateObject, + data, + el + ); + } else if (Array.isArray(options2)) { + validIdentificationOptionsArray( + options2 + ); + requestFunction( + void 0, + options2, + templateObject, + data, + el, + true + ); + } + return templateObject; }; - return hmpl; - })(); + return templateFunction; + }; + return renderTemplate( + templateEl, + renderFn, + requests, + options, + isMemoUndefined, + isAutoBodyUndefined, + isRequest + ); +}; +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + compile, + stringify }); diff --git a/www/app/docs/.vuepress/public/images/logo_new.svg b/www/app/docs/.vuepress/public/images/logo_new.svg new file mode 100644 index 0000000..026dd58 --- /dev/null +++ b/www/app/docs/.vuepress/public/images/logo_new.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/www/app/docs/.vuepress/styles/palette.scss b/www/app/docs/.vuepress/styles/palette.scss index 5cea55f..34da536 100644 --- a/www/app/docs/.vuepress/styles/palette.scss +++ b/www/app/docs/.vuepress/styles/palette.scss @@ -29,7 +29,8 @@ a::before { .vp-project-home div, .vp-project-home h1, -.vp-project-home p { +.vp-project-home p, +.vp-hero-info * { opacity: 1 !important; transform: unset !important; } diff --git a/www/app/docs/README.md b/www/app/docs/README.md index 5a5e028..eefef8a 100644 --- a/www/app/docs/README.md +++ b/www/app/docs/README.md @@ -1,6 +1,7 @@ --- home: true title: Home +heroImage: images/logo_new.svg actions: - text: Get Started link: /getting-started.html @@ -16,7 +17,7 @@ features: details: When working with server-side HTML, unlike HTMX and similar modules, you can almost completely customize requests to the server - title: Syntax icon: code - details: Work with server-side html directly in markup, passing only the object + details: The language is syntactically object-based and integrated with a robust JSON5 parser used by millions of people - title: Supportability icon: clock details: The basis of the language is fetch and the new ECMAScript and Web APIs features that come with it @@ -43,13 +44,13 @@ const templateFn = compile(

{ { - "src":"/api/register", - "after":"submit:#form", - "repeat":false, - "indicators": [ + src: "/api/register", + after: "submit:#form", + repeat: false, + indicators: [ { - "trigger": "pending", - "content": "

Loading...

" + trigger: "pending", + content: "

Loading...

" } ] } @@ -62,7 +63,7 @@ const initFn = (ctx) => { return { body: new FormData(event.target, event.submitter), - credentials: "same-origin", + credentials: "same-origin" }; }; const obj = templateFn(initFn); @@ -111,20 +112,20 @@ wrapper.appendChild(obj.response); ## Why hmpl? -The HMPL template language extends the capabilities of regular HTML by adding query objects to the markup to reduce the code on the client. When creating modern web applications, frameworks and libraries are used, which entail the need to write a bunch of boilerplate code, as well as connecting additional modules, which again make JavaScript files very large. If you recall the same SPA, then there js files can reach several hundred megabytes, which makes the first site load speed quite long. All this can be avoided by generating the markup on the server and then loading it on the client. Example of comparing the file size of a web application on Vue and HMPL.js: +The HMPL template language extends the capabilities of regular HTML by adding request objects to the markup to reduce the code on the client. When creating modern web applications, frameworks and libraries are used, which entail the need to write a bunch of boilerplate code, as well as connecting additional modules, which again make JavaScript files very large. If you recall the same SPA, then there js files can reach several hundred megabytes, which makes the first site load speed quite long. All this can be avoided by generating the markup on the server and then loading it on the client. Example of comparing the file size of a web application on Vue and HMPL.js: ```javascript createApp({ setup() { const count = ref(0); return { - count, + count }; }, template: `
Clicks: {{ count }}
-
`, + ` }).mount("#app"); ``` @@ -135,13 +136,13 @@ document.querySelector("#app").append( hmpl.compile( `
-
Clicks: {{ "src": "/api/clicks", "after": "click:button" }}
+
Clicks: {{ src: "/api/clicks", after: "click:button" }}
` )().response ); ``` -> Size: **206** bytes (4KB on disk) +> Size: **209** bytes (4KB on disk) If we do not take into account that in one case we store the state on the client, and in the other on the server, as well as the response speed from the server, then we can see that with different file sizes we get the same interface. And this is only a small example. If we take large web applications, then the file sizes there can be several times smaller. @@ -155,7 +156,7 @@ Module has its own loader for files with the `.hmpl` extension. You can include
{ { - "src":"/api/test" + src: "/api/test" } }
diff --git a/www/app/docs/changelog.md b/www/app/docs/changelog.md index 778d3bf..b7e5260 100644 --- a/www/app/docs/changelog.md +++ b/www/app/docs/changelog.md @@ -1,5 +1,12 @@ # Changelog +## 2.2.0 (2024-12-04) + +- Integration with [JSON5](https://www.npmjs.com/package/json5). Now, objects can be written in HTML just like in vanilla js +- A bug with additional nodes has been fixed when you do not specify the request object in the element +- The `.runtime` file has been updated +- Comments have been added to the file hmpl.js + ## 2.1.8 (2024-11-18) - Update package data diff --git a/www/app/docs/installation.md b/www/app/docs/installation.md index c339fd0..7e19238 100644 --- a/www/app/docs/installation.md +++ b/www/app/docs/installation.md @@ -1,8 +1,8 @@ -# Installation +## Installation -hmpl can be installed in several ways, which are described in this article. This tool is a simple javascript file that is connected in the usual way through a `script`, or using the `import` construct in an environment that supports this (webpack build, parcel build etc.). The first and easiest way is to install using a CDN. +hmpl can be installed in several ways, which are described in this section. This tool is a simple javascript file that is connected in the usual way through a `script`, or using the `import` construct in an environment that supports this (webpack build, parcel build etc.). Also, starting from version `2.2.0`, the connection of the JSON5 module is required. The first and easiest way is to install using a CDN. -## Package Manager +### Package Manager This method involves downloading through npm or other package managers. @@ -14,32 +14,35 @@ npm i hmpl-js Along the path node-modules/hmpl/dist you can find two files that contain a regular js file and a minified one. -## Manual download +### CDN -You can install the package by simply [downloading](https://unpkg.com/hmpl-js@2.1.8/dist/hmpl.min.js) it as a file and moving it to the project folder. +This method involves connecting the file through a third-party resource, which provides the ability to obtain a javascript file from npm via a link. ```html - + + + ``` -If, for some reason, you do not need the minified file, then you can download the full file from this [link](https://unpkg.com/hmpl-js@2.1.8/dist/hmpl.js). +This resource could be unpkg, skypack or other resources. The examples include unpkg simply because it is one of the most popular and its url by characters is not so long. -```html - -``` +### Manual download -The non-minified file is larger in size, but it is there as it is with all the formatting. +You can install the package by simply [downloading](https://unpkg.com/hmpl-js/dist/hmpl.min.js) it as a file and moving it to the project folder. -## CDN +```html + + +``` -This method involves connecting the file through a third-party resource, which provides the ability to obtain a javascript file from npm via a link. +If, for some reason, you do not need the minified file, then you can download the full file from this [link](https://unpkg.com/hmpl-js/dist/hmpl.js). ```html - + + ``` -This resource could be unpkg, skypack or other resources. The examples include unpkg simply because it is one of the most popular and its url by characters is not so long. +The non-minified file is larger in size, but it is there as it is with all the formatting. diff --git a/www/app/docs/introduction.md b/www/app/docs/introduction.md index 275adaf..a2c2bb2 100644 --- a/www/app/docs/introduction.md +++ b/www/app/docs/introduction.md @@ -1,6 +1,6 @@ # Introduction -🌐 hmpl is a small template language for displaying UI from server to client. It is based on requests sent to the server via [fetch](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) and processed into ready-made HTML. Reduce the size of your
javascript files and display the same UI as if it was written in a modern framework. +🌐 hmpl is a small template language for displaying UI from server to client. It is based on _customizable_ requests sent to the server via [fetch](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) and processed into ready-made HTML. The language is syntactically object-based and integrated with [JSON5](https://www.npmjs.com/package/json5). Reduce the size of your javascript files and display the same UI as if it was written in a modern framework. ## Example @@ -8,7 +8,8 @@ ```html
- + +