-
Notifications
You must be signed in to change notification settings - Fork 1
/
vpjax.min.js
6 lines (6 loc) · 5.09 KB
/
vpjax.min.js
1
2
3
4
5
6
/*!
* Copyright 2022, Halil Ibrahim Ercelik
* Released under the MIT License
* {@link https://github.com/halillusion/vpjax GitHub}
* Inspired by defunkt's jQuery-Pjax
*/ class vPjax{constructor(a,b=null){return this.version="0.8.2",this.options={selector:null,wrap:null,formSelector:null,url:null,cacheExpire:300,timeOut:1e3},null!==b&&(this.options.wrap=b),"object"!=typeof a?(this.options.selector=a,null===b&&console.error("Wrapper is not defined!")):this.mergeObject(this.options,a),this.fetch=null,this.method="GET",this.formData=null,window.vPjax={},window.onpopstate=a=>this.getBack(a),this}init(){let c=document.querySelectorAll(this.options.selector);for(let a=0;a<c.length;a++)c[a].addEventListener("click",b=>{this.handler(b,c[a])});if(this.options.formSelector){let d=document.querySelectorAll(this.options.formSelector);for(let b=0;b<d.length;b++)d[b].addEventListener("submit",a=>{this.formHandler(a,d[b])})}return this}mergeObject(b,c,f=null){if(null!==b&&null!==c){let e=Object.keys(c),a=null;for(let d=0;d<e.length;d++)a=e[d],b.hasOwnProperty(a)&&"object"==typeof c[a]?b[a]=this.mergeObject(b[a],c[a],a):b[a]=c[a]}else b=c;return b}handler(a,d){if("#"===d.getAttribute("href"))return;let c=this.urlCheck(d.getAttribute("href"));if(null===c){console.error("File protocol doesn't supported!");return}if(!1===c)return;let b=new URL(c);if(a.ctrlKey||a.shiftKey||a.altKey||a.metaKey||a.which>1)return;if(location.protocol!==b.protocol||location.hostname!==b.hostname){location.href=b;return}if(b.href.indexOf("#")> -1&&this.stripHash(b)===this.stripHash(location))return;let e=new CustomEvent("vPjax:click",{detail:{options:this.options}});return document.dispatchEvent(e),this.formData=null,this.method="GET",this.get(b),a.preventDefault(),this}urlCheck(a){let b=/(?:^|\s)((https?:\/\/)?(?:localhost|[\w-]+(?:\.[\w-]+)+)(:\d+)?(\/\S*)?)/g;return b.exec(a)?a:"file:"==window.location.protocol?null:(a=window.location.origin+a,!!b.exec(a)&&a)}reload(a=null){this.method="GET",this.formData=null,null===a&&(a=location.href),this.get(a)}formHandler(c,b){if("#"===b.getAttribute("action"))return;let a=b.getAttribute("action");if(-1===a.indexOf(location.origin)&&(a=location.origin+("/"===a.substring(0,1)?"":"/")+a),this.formData=new FormData(b),"GET"===b.getAttribute("method").toUpperCase())return;this.method="POST";let d=new CustomEvent("vPjax:submit",{detail:{options:this.options}});return document.dispatchEvent(d),this.get(a),c.preventDefault(),this}async get(a){let e=new CustomEvent("vPjax:beforeSend",{detail:{options:this.options,url:a}});document.dispatchEvent(e);let b=new AbortController;this.options.url=a;let c;this.options.timeOut&&(c=setTimeout(()=>{if(!this.fetch){let a=new CustomEvent("vPjax:timeout",{detail:{options:this.options,fetch:b}});document.dispatchEvent(a),b.abort(),location.href=this.options.url,clearTimeout(c)}},this.options.timeOut));let f=new CustomEvent("vPjax:start",{detail:{options:this.options,abort:b}});document.dispatchEvent(f);let d={method:this.method,mode:"cors",cache:"no-cache",credentials:"same-origin",headers:{"X-VPJAX":!0},redirect:"follow",referrerPolicy:"same-origin",signal:b.signal};if(this.formData&&(d.body=this.formData),this.fetch=await fetch(this.options.url,d).then(function(a){if(a.headers.get("refresh")){let b=a.headers.get("refresh").replace(" ","");window.vPjax.refresh=b.split(";url=")}return a.headers.get("location")&&(window.vPjax.location=a.headers.get("location")),!!a.ok&&a.text()}).then(function(a){let b=new CustomEvent("vPjax:success",{detail:{dom:a.dom}});return document.dispatchEvent(b),a}).catch(function(a){let b=new CustomEvent("vPjax:error",{detail:{error:a}});throw document.dispatchEvent(b),a}),window.vPjax.location){let g=this.urlCheck(window.vPjax.location);return this.get(g),window.vPjax.location=null,this}if(window.vPjax.refresh){let h=this.urlCheck(window.vPjax.refresh[1]);setTimeout(()=>{this.get(h)},1e3*parseInt(window.vPjax.refresh[0])),window.vPjax.refresh=null}return this.fetch&&(this.loadContent(this.fetch),this.options.timeOut&&clearTimeout(c),this.fetch=null),this}loadContent(d,g=!1){let h=new DOMParser,a=h.parseFromString(d,"text/html"),b=a.querySelector(this.options.wrap);if(b){let c=document.querySelector(this.options.wrap);if(c){let i=new CustomEvent("vPjax:beforeExtract",{detail:{options:this.options,dom:a}});document.dispatchEvent(i);let j=b.innerHTML,e=document.querySelector("title").textContent;c.innerHTML=j,c.className=b.className,(e=a.querySelector("title").textContent)&&(document.querySelector("title").textContent=e);let f=new URL(this.options.url);g?window.history.back(-1):window.history.pushState({},"",f);let k=new CustomEvent("vPjax:finish",{detail:{options:this.options,url:f}});document.dispatchEvent(k),this.init()}else throw location.href=this.options.url,"The element specified as selector does not exist!"}else throw location.href=this.options.url,"Server response is not correct! -> "+d;return this}stripHash(a){return a.href.replace(/#.*/,"")}form(a){return this.options.formSelector=a,this}getBack(b){let a=new CustomEvent("vPjax:popstate",{detail:{options:this.options,url:document.location}});document.dispatchEvent(a),this.get(document.location)}}