diff --git a/public/scripts/hyperwave.js b/public/scripts/hyperwave.js index ff1897a..44ff0eb 100644 --- a/public/scripts/hyperwave.js +++ b/public/scripts/hyperwave.js @@ -1 +1 @@ -const hyperwaveConfig={debug:!0,defaultMethod:"GET",defaultDebounceDelay:50,defaultLimit:32,defaultTotalItems:2048,logPrefix:"hyperwave:"},log=(e,...t)=>{hyperwaveConfig.debug&&console[e](`${hyperwaveConfig.logPrefix}`,...t)},createDebouncedFunction=(e,t)=>{let r;return(...n)=>{clearTimeout(r),r=setTimeout((()=>e.apply(this,n)),t)}},fetchContent=async(e,t={})=>{const r={method:t.method||hyperwaveConfig.defaultMethod,headers:{Accept:"text/html",...t.headers},...t};try{const t=await fetch(e,r);if(!t.ok)throw new Error(`HTTP error! status: ${t.status}`);const n=await t.text();return log("log",`Content fetched from ${e}`,n.length),n}catch(t){return log("error",`Error fetching from ${e}:`,t),null}},updateTargetElement=(e,t,r="replace")=>{if("replace"===r)e.innerHTML=t;else if("append"===r){const r=document.createElement("div");for(r.innerHTML=t;r.firstChild;)e.appendChild(r.firstChild)}attachHyperwaveHandlers(e)},buildPaginationUrl=(e,t,r)=>{const n=new URL(e.getAttribute("href"),window.location.origin);return n.searchParams.set("offset",t),n.searchParams.set("limit",r),n.toString()},handlePagination=(e,t)=>{let r=parseInt(e.getAttribute("offset")||"0",10);const n=parseInt(e.getAttribute("limit")||hyperwaveConfig.defaultLimit,10),o=parseInt(e.getAttribute("total")||hyperwaveConfig.defaultTotalItems,10),a=e.getAttribute("update-mode")||"replace";let l=!1;return async()=>{if(l||r>=o)return;l=!0;const i=buildPaginationUrl(e,r,n),d=await fetchContent(i,t);if(d){const t=document.querySelector(e.getAttribute("target"));updateTargetElement(t,d,a),r+=n,e.setAttribute("offset",r),log("log",`Content updated. New offset set: ${r}`)}l=!1}},setupEventHandlers=e=>{const t=e.getAttribute("method")||hyperwaveConfig.defaultMethod,r=e.getAttribute("trigger")||"click",n=parseInt(e.getAttribute("debounce")||hyperwaveConfig.defaultDebounceDelay,10),o=parseInt(e.getAttribute("scroll-threshold")||"300",10),a={method:t.toUpperCase(),headers:{Accept:"text/html"}};log("log",`Setting up event handlers: method=${t}, trigger=${r}, debounceDelay=${n}, scrollThreshold=${o}`);const l=handlePagination(e,a),i=createDebouncedFunction((async e=>{if("scroll"!==r&&e.preventDefault(),"scroll"===r){if(!(document.body.offsetHeight-(window.innerHeight+window.scrollY)<=o))return}await l()}),n);if("DOMContentLoaded"===r)l();else{("scroll"===r?window:e).addEventListener(r,i),e._hyperwaveHandler=i,"scroll"===r&&l()}},attachHyperwaveHandlers=e=>{Array.from(e.querySelectorAll("[href]")).filter((e=>!["A","LINK"].includes(e.tagName))).forEach((e=>setupEventHandlers(e)))};document.addEventListener("DOMContentLoaded",(()=>{log("log","DOMContentLoaded event triggered"),attachHyperwaveHandlers(document);new MutationObserver((e=>{e.forEach((e=>{e.addedNodes.forEach((e=>{e.nodeType===Node.ELEMENT_NODE&&(log("log","MutationObserver detected new element:",e),attachHyperwaveHandlers(e))}))}))})).observe(document.body,{childList:!0,subtree:!0})})); \ No newline at end of file +const hyperwaveConfig={debug:!0,defaultMethod:"GET",defaultDebounceDelay:50,defaultLimit:32,defaultTotalItems:2048,logPrefix:"hyperwave:"},log=(e,...t)=>{hyperwaveConfig.debug&&console[e](`${hyperwaveConfig.logPrefix}`,...t)},createDebouncedFunction=(e,t)=>{let r;return(...o)=>{clearTimeout(r),r=setTimeout((()=>e.apply(this,o)),t)}},fetchContent=async(e,t={})=>{const r={method:t.method||hyperwaveConfig.defaultMethod,headers:{Accept:"text/html",...t.headers},...t};try{const t=await fetch(e,r);if(!t.ok)throw new Error(`HTTP error! status: ${t.status}`);const o=await t.text();return log("log",`Content fetched from ${e}`,o.length),o}catch(t){return log("error",`Error fetching from ${e}:`,t),null}},updateTargetElement=(e,t,r="replace")=>{if("replace"===r)e.innerHTML=t;else if("append"===r){const r=document.createElement("div");for(r.innerHTML=t;r.firstChild;)e.appendChild(r.firstChild)}attachHyperwaveHandlers(e)},buildPaginationUrl=(e,t,r)=>{const o=new URL(e.getAttribute("href"),window.location.origin);return o.searchParams.set("offset",t),o.searchParams.set("limit",r),o.toString()},handlePagination=(e,t)=>{let r=parseInt(e.getAttribute("offset")||"0",10);const o=parseInt(e.getAttribute("limit")||hyperwaveConfig.defaultLimit,10),n=parseInt(e.getAttribute("total")||hyperwaveConfig.defaultTotalItems,10),a=e.getAttribute("update-mode")||"replace";let i=!1;return async()=>{if(i||r>=n)return;i=!0;const l=buildPaginationUrl(e,r,o),d=await fetchContent(l,t);if(d){const t=document.querySelector(e.getAttribute("target"));updateTargetElement(t,d,a),r+=o,e.setAttribute("offset",r),log("log",`Content updated. New offset set: ${r}`)}i=!1}},setupEventHandlers=e=>{const t=e.getAttribute("method")||hyperwaveConfig.defaultMethod,r=e.getAttribute("trigger")||"click",o=parseInt(e.getAttribute("debounce")||hyperwaveConfig.defaultDebounceDelay,10),n=parseInt(e.getAttribute("scroll-threshold")||"300",10),a={method:t.toUpperCase(),headers:{Accept:"text/html"}};log("log",`Setting up event handlers: method=${t}, trigger=${r}, debounceDelay=${o}, scrollThreshold=${n}`);const i=handlePagination(e,a),l=createDebouncedFunction((async e=>{if("scroll"!==r&&e.preventDefault(),"scroll"===r){if(!(document.body.offsetHeight-(window.innerHeight+window.scrollY)<=n))return}await i()}),o);if("DOMContentLoaded"===r)i();else{("scroll"===r?window:e).addEventListener(r,l),e._hyperwaveHandler=l,"scroll"===r&&i()}},attachHyperwaveHandlers=e=>{Array.from(e.querySelectorAll("[href]")).filter((e=>!["A","LINK"].includes(e.tagName))).forEach((e=>setupEventHandlers(e)))};document.addEventListener("DOMContentLoaded",(()=>{log("log","DOMContentLoaded event triggered"),attachHyperwaveHandlers(document);new MutationObserver((e=>{e.forEach((e=>{e.addedNodes.forEach((e=>{e.nodeType===Node.ELEMENT_NODE&&(log("log","MutationObserver detected new element:",e),attachHyperwaveHandlers(e))}))}))})).observe(document.body,{childList:!0,subtree:!0});document.querySelectorAll("form[href]").forEach((e=>{e.addEventListener("submit",(t=>{t.preventDefault(),log("log","Form submission intercepted",e);const r={method:e.getAttribute("method")||hyperwaveConfig.defaultMethod,headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(new FormData(e)).toString()},o=new URL(e.getAttribute("href"),window.location.origin);fetchContent(o.toString(),r).then((t=>{const r=document.querySelector(e.getAttribute("target")||"#trip-details");updateTargetElement(r,t,"replace")}))}))}))})); \ No newline at end of file