diff --git a/interfy.min.js b/interfy.min.js index 08059d6..9cdee75 100644 --- a/interfy.min.js +++ b/interfy.min.js @@ -2,7 +2,7 @@ * Interfy - A Javascript library for robust web front-end routing. * * Github's repo - https://github.com/DenisPower1/interfy - * version - 2.0.0 + * version - 2.0.1 * * Created by - Denis Power/ https://github.com/DenisPower1 * @@ -10,4 +10,4 @@ */ -!function(){if(null==typeof window&&"object"==typeof global&&"function"==typeof process.on)throw new Error("\n \n Interfy is a client-side Javascript routing library,\n you can only use it in a browser.\n\n ");if("file:"==window.location.protocol)throw new Error('\n\t\t\n\t\tInterfy can only be used in an "http:" or "https:" protocol.\n\t\t\n\t\t');String.is=function(n){return"[object String]"==t.toString.apply(n,void 0)},String.prototype.has=function(t){if(t instanceof RegExp)return t.test(this)},String.prototype.trimAll=function(){return this.replace(/\s/g,"")};const t=Object.prototype;function n(n){return"[object Function]"==t.toString.call(n)}const e={sy(t){const n=new SyntaxError;throw n.message=t,n},err(t){const n=new Error;throw n.message=t,n},wrn:t=>console.warn(t)};function o(t,n){let o;var r;null==o&&(o=function(){const t=globalThis;return!(!t.Inter||"development"==t.app.status)}()),r=o,Object.is(!1,r)&&e[t](n)}function r(t,n){if(n){const n=window.location.hash;if(n){""==n.replace(/#/g,"")?window.history.pushState(null,null,`#${t}`):window.history.replaceState(null,null,`#${t}`)}else{"/"==window.location.pathname?window.history.pushState(null,null,`#${t}`):window.history.replaceState(null,null,`#${t}`)}}else{"/"==window.location.pathname?window.history.pushState(null,null,t):window.history.replaceState(null,null,t)}}const s=new Map;s.set("path",void 0);const a=Symbol.for("callBack"),i={[a]:void 0,get url(){return s.get("path")},has:t=>t.has(/\((:?[\s\S]+)\)|\*/g),is(t){const n=this.url,e=t.replace(/\((:?[\s\S]+)\)|\*/g,"[\\s\\S]");return(new RegExp).compile(e).test(n)},getVar:t=>(class{constructor(){}get url(){return s.get("path").trimAll()}static getVar(t){const n=new Array,e=new Array;t.replace(/\/(:?[a-z]+)\/|\/(\d+)/g,(t,e)=>{n.push(t)}),t.replace(/\((:?[a-z]+)\)/g,(t,n)=>{e.push(n)});let o=this.prototype.url.replace(/-|_/g,(t,n)=>"_"==t?"d".repeat("down".length):"-"==t?"m".repeat("middle".length):void 0);for(let t of n)o=o.replace(t,"/");const r=Object.create(null);let s=-1;return o.replace(/(\w+|\d+|[a-z]+)/g,(t,n)=>{s++;let o=n;o.includes("mmmmmm")&&(o=o.replace(/mmmmmm/g,"-")),o.includes("dddd")&&(o=o.replace(/dddd/g,"_")),r[e[s]]=o}),r}}).getVar(t)};function l(){null==new.target&&o("sy","\n \n Invoke the [INTERFY CONSTRUCTOR] only\n with the new keyword.\n\n \n ")}function u(t,n){const e=t.next().value;Object.defineProperty(n,e[0],{get:()=>e[1]}),t.next().done||u(t,n)}Object.preventExtensions(i);const c=Object.create(null),h=new Map;let p=!1;function d(){this.start=function(t=(()=>{})){if(p)return o("wrn","\n \n The router was already started.\n\n "),!1;const e=Object.keys(c).length>0;if(e){p=!0,(new l).createRouter(e=>{let o=!1;n(t)&&t(e.url);for(let[t,n]of Object.entries(c)){if(e.url==t){n(Object.create(null)),o=!0;break}if(e.has(t)&&e.is(t)){const r=window.location.search;if(o=!0,r){const o=new URLSearchParams(r),s=Object.create(null);u(o.entries(),s),n(e.getVar(t),s)}else n(e.getVar(t))}}if(!o&&h.has("notfound")){h.get("notfound")(e.url)}})}e||o("sy","\n \n The router can not start, because you did not\n register any route.\n \n ")},this.route=function(t,e){if(p)return o("wrn","\n \n You already started the router, so you\n can not add more routes to it.\n \n "),!1;const r=String.is(t);if(arguments.length<2&&o("sy",`\n \n The route method accepts two arguments,\n and you defined: ${arguments.length}.\n\n\n `),r||o("sy",'\n \n The first argument of [ INTERFY INSTANCE ].route \n must be a string.\n\n [INTERFY INSTANCE].route("/routename", ()=>{})\n\n '),n(e)||o("sy","\n \n \n The second argument of [ INTERFY INSTANCE ].route\n must be a function.\n\n "),t.startsWith("/")||"*"==t){if("*"==t&&!h.has("notfound"))return h.set("notfound",e),!1;t in c||(c[t]=e)}else o("sy",`\n \n Routes must starts with slash(/).\n it must be "/${t}" instead of "${t}".\n\n `)}}let w=!1;l.prototype={createRouter(t){if(w)o("err","\n The router was already created.\n ");else if(w=!0,n(t)){if(i[a]=t,window.location.hash){const t=window.location.hash.replace(/#/g,"");s.set("path",t),i[a](i)}else s.set("path",window.location.pathname),i[a](i)}else o("sy",`\n \n [ INTERFY INSTANCE ].createRouter() accepts only\n a function as its argument, and you defined\n "${typeof t}" as its argument.\n \n `)}},d.prototype={setPath(t){p||o("err","\n \n The router was not started yet, start it firt.\n\n "),(0,String.is)(t)||o("sy","\n \n The pathName in [ INTERFY INSTANCE ].useHash(pathName)\n must be a string.\n \n "),t.startsWith("/")||o("sy",`\n A pathName must start with a slash(/).\n \n You used:\n \n [INTERFY INSTANCE ].setPath("${t}") \n \n `),r(t),s.set("path",t),i[a](i)},useHash(t){p||o("err","\n \n The router was not started yet, start it firt.\n\n "),String.is(pathname)||o("sy","\n \n The pathName in [ INTERFY INSTANCE ].useHash(pathName)\n must be a string.\n \n "),t.startsWith("/")||o("sy",`\n A pathName must start with a slash(/).\n \n You used:\n \n [ INTERFY INSTANCE ].useHash(${t}) \n \n `),r(t,!0),s.set("path",t),i[a](i)},get version(){return"2.0.0"}},window.onpopstate=function(){const t=this.location.hash,n=this.location.search;if(n){const t=`${this.location.pathname}${n}`;return s.set("path",t),i[a](i),!1}if(t){const n=t.replace(/#/g,"");s.set("path",""==n?"/":n),i[a](i)}else{const t=this.location.pathname;s.set("path",t),i[a](i)}},globalThis.Interfy=d}(); +!function(){if(null==typeof window&&"object"==typeof global&&"function"==typeof process.on)throw new Error("\n \n Interfy is a client-side Javascript routing library,\n you can only use it in a browser.\n\n ");if("file:"==window.location.protocol)throw new Error('\n\t\t\n\t\tInterfy can only be used in an "http:" or "https:" protocol.\n\t\t\n\t\t');String.is=function(n){return"[object String]"==t.toString.apply(n,void 0)},String.prototype.has=function(t){if(t instanceof RegExp)return t.test(this)},String.prototype.trimAll=function(){return this.replace(/\s/g,"")};const t=Object.prototype;function n(n){return"[object Function]"==t.toString.call(n)}function e(t){return Object.is(!1,t)}const o={sy(t){const n=new SyntaxError;throw n.message=t,n},err(t){const n=new Error;throw n.message=t,n},wrn:t=>console.warn(t)};function r(t,n){e(f.prototype.production)&&o[t](n)}function s(t,n){if(n){const n=window.location.hash;if(n){""==n.replace(/#/g,"")?window.history.pushState(null,null,`#${t}`):window.history.replaceState(null,null,`#${t}`)}else{"/"==window.location.pathname?window.history.pushState(null,null,`#${t}`):window.history.replaceState(null,null,`#${t}`)}}else{"/"==window.location.pathname?window.history.pushState(null,null,t):window.history.replaceState(null,null,t)}}const a=new Map;a.set("path",void 0);const i=Symbol.for("callBack"),l={[i]:void 0,get url(){return a.get("path")},has:t=>t.has(/\((:?[\s\S]+)\)|\*/g),is(t){const n=this.url,e=t.replace(/\((:?[\s\S]+)\)|\*/g,"[\\s\\S]");return(new RegExp).compile(e).test(n)},getVar:t=>(class{constructor(){}get url(){return a.get("path").trimAll()}static getVar(t){const n=new Array,e=new Array;t.replace(/\/(:?[a-z]+)\/|\/(\d+)/g,(t,e)=>{n.push(t)}),t.replace(/\((:?[a-z]+)\)/g,(t,n)=>{e.push(n)});let o=this.prototype.url.replace(/-|_|\./g,(t,n)=>"_"==t?"d".repeat("down".length):"-"==t?"m".repeat("middle".length):"."==t?"p".repeat("point".length):void 0);for(let t of n)o=o.replace(t,"/");const r=Object.create(null);let s=-1;return o.replace(/(\w+|\d+|[a-z]+)/g,(t,n)=>{s++;let o=n;o.includes("mmmmmm")&&(o=o.replace(/mmmmmm/g,"-")),o.includes("dddd")&&(o=o.replace(/dddd/g,"_")),o.includes("ppppp")&&(o=o.replace(/ppppp/g,".")),r[e[s]]=o}),r}}).getVar(t)};function u(){null==new.target&&r("sy","\n \n Invoke the [INTERFY CONSTRUCTOR] only\n with the new keyword.\n\n \n ")}function c(t,n){const e=t.next(),o=e.value;e.done||(Object.defineProperty(n,o[0],{get:()=>o[1],configurable:!0}),c(t,n))}Object.preventExtensions(l);const h=Object.create(null),p=new Map;let d=!1;function f(){this.start=function(t=(()=>{})){if(d)return r("wrn","\n \n The router was already started.\n\n "),!1;const e=Object.keys(h).length>0;if(e){d=!0,(new u).createRouter(e=>{let o=!1;n(t)&&t(e.url);for(let[t,n]of Object.entries(h)){if(e.url==t){n(Object.create(null)),o=!0;break}if(e.has(t)&&e.is(t)){const r=window.location.search;if(o=!0,r){const o=new URLSearchParams(r),s=Object.create(null);c(o.entries(),s),n(e.getVar(t),s)}else n(e.getVar(t))}}if(!o&&p.has("notfound")){p.get("notfound")(e.url)}})}e||r("sy","\n \n The router can not start, because you did not\n register any route.\n \n ")},this.route=function(t,e){if(d)return r("wrn","\n \n You already started the router, so you\n can not add more routes to it.\n \n "),!1;const o=String.is(t);if(arguments.length<2&&r("sy",`\n \n The route method accepts two arguments,\n and you defined: ${arguments.length}.\n\n\n `),o||r("sy",'\n \n The first argument of [ INTERFY INSTANCE ].route \n must be a string.\n\n [INTERFY INSTANCE].route("/routename", ()=>{})\n\n '),n(e)||r("sy","\n \n \n The second argument of [ INTERFY INSTANCE ].route\n must be a function.\n\n "),t.startsWith("/")||"*"==t){if("*"==t&&!p.has("notfound"))return p.set("notfound",e),!1;t in h||(h[t]=e)}else r("sy",`\n \n Routes must starts with slash(/).\n it must be "/${t}" instead of "${t}".\n\n `)}}let w=!1;u.prototype={createRouter(t){if(w)r("err","\n The router was already created.\n ");else if(w=!0,n(t)){if(l[i]=t,window.location.hash){const t=window.location.hash.replace(/#/g,"");a.set("path",t),l[i](l)}else a.set("path",window.location.pathname),l[i](l)}else r("sy",`\n \n [ INTERFY INSTANCE ].createRouter() accepts only\n a function as its argument, and you defined\n "${typeof t}" as its argument.\n \n `)}};let g=!1;f.prototype={get version(){return"2.0.1"},get production(){return g},set production(t){if(!this.production){if(e(t))return;if(n=t,!Object.is(!0,n))throw new TypeError(`\n \n "${t}" is an invalid value for the\n [INTERFY INSTANCE].production, property.\n If you want to turn on the production mode set it to true.\n \n `);g=!0,console.log("\n \n You are now using Interfy in production mode.\n\n ")}var n},setPath(t){d||r("err","\n \n The router was not started yet, start it firt.\n\n "),(0,String.is)(t)||r("sy","\n \n The pathName in [ INTERFY INSTANCE ].useHash(pathName)\n must be a string.\n \n "),t.startsWith("/")||r("sy",`\n A pathName must start with a slash(/).\n \n You used:\n \n [INTERFY INSTANCE ].setPath("${t}") \n \n `),s(t),a.set("path",t),l[i](l)},useHash(t){d||r("err","\n \n The router was not started yet, start it firt.\n\n "),String.is(pathname)||r("sy","\n \n The pathName in [ INTERFY INSTANCE ].useHash(pathName)\n must be a string.\n \n "),t.startsWith("/")||r("sy",`\n A pathName must start with a slash(/).\n \n You used:\n \n [ INTERFY INSTANCE ].useHash(${t}) \n \n `),s(t,!0),a.set("path",t),l[i](l)}},window.onpopstate=function(){const t=this.location.hash,n=this.location.search;if(n){const t=`${this.location.pathname}${n}`;return a.set("path",t),l[i](l),!1}if(t){const n=t.replace(/#/g,"");a.set("path",""==n?"/":n),l[i](l)}else{const t=this.location.pathname;a.set("path",t),l[i](l)}},globalThis.Interfy=f}();