-
Notifications
You must be signed in to change notification settings - Fork 0
/
spaux.min.js
1 lines (1 loc) · 8.86 KB
/
spaux.min.js
1
!function(spaux,undefined){const postfetchEvent=eventInfo=>{const targetElement=document.querySelector(eventInfo.detail.target);targetElement.removeAttribute("aria-label"),targetElement.classList.remove("spaux-in"),targetElement.classList.add("spaux-out"),window.dispatchEvent(new CustomEvent("spaux:postfetch",eventInfo)),document.head.querySelectorAll(".spaux-remove").forEach(element=>{element.remove()})};spaux.isFetching=!1,spaux.fetchToFrame=(url,target,{append:append=!1,method:method="get",callback:callback}={})=>{url=new URL(url,document.location.href).href;const targetSelector=":root"===target?":root":`#${target}`,targetElement=document.querySelector(targetSelector);targetElement.setAttribute("aria-label","Loading...");const postFetchCallback=()=>{callback&&setTimeout(callback,500),attachEvents()},eventInfo={detail:{url:url,method:method,target:targetSelector}};document.querySelector(eventInfo.detail.target).classList.remove("spaux-out"),document.querySelector(eventInfo.detail.target).classList.add("spaux-in"),window.dispatchEvent(new CustomEvent("spaux:prefetch",eventInfo)),spaux.isFetching||(spaux.isFetching=!0,fetch(url,{method:method}).then(response=>response.text()).then(html=>{if(html=html.replace(/(\s|\n)(const|let) /gim," var "),!targetElement)return void console.error(`target ${target} not found`);if(":root"===target||!append&&url!==document.location.href){const headRegex=/<head>((.|\n)*)<\/head>/gim;let m=headRegex.exec(html);null!==m&&_loadContent(_htmlToElements(m[1]),0,document.head,!1)}if(":root"===target){const doc=(new DOMParser).parseFromString(html,"text/html");return document.body.innerHTML="",document.body.className="",void setTimeout(()=>{document.body.className=doc.body.className,document.body.innerHTML=doc.body.innerHTML,postFetchCallback(),postfetchEvent(eventInfo)},150)}let contentRegex=new RegExp(`<(\\w+)(.*?) id="${target}"(.*?)>((.|\\n)*)`,"gmi");if(m=contentRegex.exec(html),null===m)contentRegex=/<body((.|\n)*)?>((.|\n)*)<\/body>/gim,m=contentRegex.exec(html),null!==m&&(html=m[0]);else{const tag=m[1];contentRegex=new RegExp(`^(<${tag}(.*?) id="${target}"(.*?)>((.|\\n)*)</${tag}>)|</${tag}>$`,"gmi"),m=contentRegex.exec(m[0]),html=`${m.slice(-2)[0]}`.split(`</${tag}>`).slice(0,-1).join(`</${tag}>`)}setTimeout(()=>{spaux.placeHTML(html,targetSelector,append).then(postFetchCallback),postfetchEvent(eventInfo)},200)}).catch(error=>{console.log(error),postfetchEvent(eventInfo)}).finally(()=>{setTimeout(()=>{spaux.isFetching=!1},300)}))};const onClick=event=>{event.preventDefault();let el=event.target;for(;el&&!el.hasAttribute("href");)if(el=el.parentNode,"BODY"==el.nodeName)return;const target=el.getAttribute("data-spaux-target")||":root",method=el.getAttribute("data-spaux-method")||"get",append=el.hasAttribute("data-spaux-append")&&"false"!==el.getAttribute("data-spaux-append"),render=!el.hasAttribute("data-spaux-render")||"false"!==el.getAttribute("data-spaux-render"),cache=!el.hasAttribute("data-spaux-cache")||"false"!==el.getAttribute("data-spaux-cache"),url=new URL(el.getAttribute("href"),document.location.href).href;if(el.target&&"_self"!==el.target)return void window.open(url,el.target);try{let parent=el;for(;parent&&("A"==parent.nodeName||"LI"==parent.nodeName)&&(parent=parent.parentNode,"BODY"!=parent.nodeName););parent.querySelectorAll("a").forEach(element=>{element.classList.remove("spaux-active")}),el.classList.add("spaux-active")}catch(err){}if(!render)return void fetch(url,{method:method}).then(response=>{console.log(response)}).catch(error=>{console.error(error)});const targetSelector=document.querySelector(":root"===target?target:`#${target}`),state={title:document.title,html:targetSelector.innerHTML.trim(),method:method,target:target,cache:cache,url:document.location.href,scrollY:window.scrollY,scrollX:window.scrollX};spaux.fetchToFrame(url,target,{append:append,method:method,callback:()=>{const changeInterval=setInterval(()=>{""!==targetSelector.innerHTML&&state.html!==targetSelector.innerHTML.trim()&&(clearInterval(changeInterval),state.html=targetSelector.innerHTML.trim(),state.url=url,append&&url==document.location.href?history.replaceState(state,url,url):history.pushState(state,url,url))},1)}})},onSubmit=event=>{event.preventDefault();const el=event.target,target=el.getAttribute("data-spaux-target")||el.getAttribute("data-spaux-id"),append=el.hasAttribute("data-spaux-append")&&"false"!==el.getAttribute("data-spaux-append");let targetSelector=":root"===target?target:`#${target}`;target===el.getAttribute("data-spaux-id")&&(targetSelector=`[data-spaux-id="${target}"]`);const callback=window[el.getAttribute("data-spaux-callback")]||function(){el.reset()};fetch(el.action,{method:el.method||"post",body:new URLSearchParams(new FormData(el))}).then(response=>response.text()).then(html=>{""!==html?spaux.placeHTML(html,targetSelector,append).then(()=>{callback(el),console.info("form replaced")}):callback(el)}).catch(error=>{console.error("Error:",error)})};spaux.remoteResources=[],setInterval(()=>{spaux.remoteResources=[]},3e5);const _htmlToElements=function(html){var template=document.createElement("template");template.innerHTML=html;const nodes=template.content.childNodes,nodesArray=[],scriptsArray=[];for(var i in nodes)1==nodes[i].nodeType&&("SCRIPT"===nodes[i].nodeName?scriptsArray.push(nodes[i]):nodesArray.push(nodes[i]));return nodesArray.concat(scriptsArray)},_loadContent=function(data,index,container,appendData){var item,minified;if(0!==index||appendData||(container===document.head?(document.head.querySelectorAll('link[rel="stylesheet"], style').forEach(element=>{element.classList.add("spaux-remove")}),document.head.querySelectorAll(':not(link[rel="stylesheet"]):not(style)').forEach(element=>{element.remove()})):document.querySelector(container).innerHTML=""),!(index<=data.length))return!0;var element=data[index];void 0!==element&&"SCRIPT"==element.nodeName?(item=document.createElement(element.nodeName.toLowerCase()),element.type&&(item.type=element.type),Array.prototype.forEach.call(element.attributes,(function(attr){item.setAttribute(attr.nodeName,attr.nodeValue)})),""!=element.src?!1===spaux.remoteResources.includes(element.src)&&(spaux.remoteResources.push(element.src),item.src=element.src,item.onload=function(){_loadContent(data,index+1,container)},document.head.appendChild(item)):(minified=element.text.replace(/[^a-z0-9]/gim,""),!1===spaux.remoteResources.includes(minified)&&(spaux.remoteResources.push(minified),item.text=element.text,document.body&&document.body.appendChild(item)),_loadContent(data,index+1,container))):void 0!==element&&"LINK"==element.nodeName&&"stylesheet"==element.rel?(item=document.createElement(element.nodeName.toLowerCase()),element.type&&(item.type=element.type),Array.prototype.forEach.call(element.attributes,(function(attr){item.setAttribute(attr.nodeName,attr.nodeValue)})),!1===spaux.remoteResources.includes(element.href)?(spaux.remoteResources.push(element.href),item.href=element.href,item.onload=function(){_loadContent(data,index+1,container)},item.classList.remove("x-spaux-remove"),document.head.appendChild(item)):_loadContent(data,index+1,container)):(void 0!==element&&(container===document.head?document.head.appendChild(element):document.querySelector(container).appendChild(element)),_loadContent(data,index+1,container))},attachEvents=element=>{"string"==typeof(element=element||document)&&(element=document.querySelector(element)),element.querySelectorAll("a:not([data-spaux-disable])").forEach(el=>{el.removeEventListener("click",onClick),el.addEventListener("click",onClick)}),element.querySelectorAll("form:not([data-spaux-disable])").forEach(el=>{el.setAttribute("data-spaux-id",`spaux#${Math.random().toString(36).substring(2)}`),el.removeEventListener("submit",onSubmit),el.addEventListener("submit",onSubmit)})};spaux.init=()=>{localStorage.setItem("originalState",JSON.stringify({title:document.title,html:document.querySelector("body").innerHTML.trim()})),attachEvents(),window.addEventListener("popstate",event=>{event.preventDefault();let targetSelector=":root";if(null!==event.state)event.state&&(targetSelector=`#${event.state.target}`,event.state.cache?spaux.placeHTML(event.state.html,targetSelector).then(()=>{window.scrollTo(event.state.scrollX,event.state.scrollY),document.title=event.state.title}):spaux.fetchToFrame(event.state.url,event.state.target,{append:!1,method:event.state.method,callback:()=>{window.scrollTo(event.state.scrollX,event.state.scrollY),document.title=event.state.title}})),attachEvents(targetSelector);else if(localStorage.getItem("originalState")){const originalState=JSON.parse(localStorage.getItem("originalState"));document.title=originalState.title,spaux.placeHTML(originalState.html,"body").then(()=>{})}})},document.addEventListener("DOMContentLoaded",()=>{spaux.init()}),spaux.placeHTML=async function(data,container,appendData=!1){return data="<"===data.trim().substring(0,1)?data:`<div>${data}</div>`,_loadContent(_htmlToElements(data),0,container,appendData)}}(window.spaux=window.spaux||{});