svelte-pathfinder
Version:
Tiny, state-based, advanced router for SvelteJS.
3 lines (2 loc) • 10.4 kB
JavaScript
import{tick as e}from"svelte";import{writable as t,get as n,derived as o}from"svelte/store";const r=/^((mailto:)|(tel:)|(sms:)|(data:)|(blob:)|(javascript:)|(ftp(s?):\/\/)|(file:\/\/))/,s="undefined"!=typeof location,i="undefined"!=typeof process,c="undefined"!=typeof history,a=c&&R(history.pushState),u="undefined"!=typeof window,l=u&&window!==window.parent,f=s&&("file:"===location.protocol||/[-_\w]+[.][\w]+$/i.test(location.pathname)),d=u&&c&&s&&!l,h=!a||f,p="#!",b={array:{separator:",",format:"bracket"},convertTypes:!0,breakHooks:!0,hashbang:!1,anchor:!1,scroll:!1,focus:!1,nesting:3,sideEffect:d,base:""};function m(){if(!s)return{};if(b.hashbang||h){const e=location.hash;return new URL(0===e.indexOf(p)?e.substring(2):e.substring(1),"file:")}return location}function g(){return b.base?b.base:s&&(b.hashbang||h)?location.pathname:"/"}function y(e){(b.hashbang||h)&&(e=p+e);const t=g();return("/"===t[t.length-1]?t.substring(0,t.length-1):t)+e}function w(e){e=x(e,m().origin);return e=x(e,g()),(b.hashbang||h)&&(e=x(e,p)),E(e)}function v(e){const t=e.tagName.toLowerCase(),n=e.type&&e.type.toLowerCase();return"button"===t||"input"===t&&["button","submit","image"].includes(n)}function O(e,t=""){const n=x(A(t),"#");if(e&&b.scroll){const t=S(b.scroll)?{...b.scroll,...e}:e,{top:n=0,left:o=0}=e,{scrollHeight:r,scrollWidth:s}=document.documentElement;if(n<=r&&o<=s)return I(t);const i=function(e,t,n=5e3){const o=new ResizeObserver(e);o.observe(t);const r=()=>o.unobserve(t);return setTimeout(r,n),r}((e=>{if(!e[0])return i();(!n||e[0].contentRect.height>=n)&&(!o||e[0].contentRect.width>=o)&&(i(),I(t))}),document.documentElement)}else if(n&&b.anchor){const e=S(b.anchor)?b.anchor:{},t=document.getElementById(n);if(t)return I(e,t);const o=L((()=>{const t=document.getElementById(n);t&&(o(),I(e,t))}))}else b.scroll&&I()}function $(e={},{encode:t=encodeURIComponent}={}){return Object.keys(e).reduce(((n,o)=>{if(Object.prototype.hasOwnProperty.call(e,o)&&isNaN(parseInt(o,10)))if(Array.isArray(e[o]))"separator"===b.array.format?n.push(`${o}=${e[o].join(b.array.separator)}`):e[o].forEach((e=>n.push(`${o}[]=${t(e)}`)));else if(S(e[o])){let t=C(o,e[o]);n.push(T(t))}else n.push(`${o}=${t(e[o])}`);return n}),[]).join("&")}function j(e="",t="*",{loose:n=!1,sensitive:o=!1,blank:r=!1,decode:s=decodeURIComponent}={}){const i={},c=t instanceof RegExp?t:t.split("/").reduce(((e,t,o,{length:r})=>{if(t){const n=t[0];if("*"===n)i.wild=void 0,e+="/(?<wild>.*)";else if(":"===n){const n=t.indexOf("?",1),o=t.indexOf(".",1),r=!!~n,s=!!~o,c=t.substring(1,r?n:s?o:t.length);i[c]=void 0,e+=r&&!s?`(?:/(?<${c}>[^/]+?))?`:`/(?<${c}>[^/]+?)`,s&&(e+=`${r?"?":""}\\${t.substring(o)}`)}else e+=`/${t}`}return o===r-1&&(e+=n?"(?:$|/)":"/?$"),e}),"^"),a=new RegExp(c,o?"":"i").exec(e);return a?Object.entries(a.groups||{}).reduce(((e,[t,n])=>{const o=s(n);return e[t]=b.convertTypes?N(o):o,e}),{}):r?i:null}function A(e,{decode:t=decodeURIComponent}={}){return t(e)}function E(e,t="/",n=!1){return!(e+="")&&n?e:0!==e.indexOf(t)?t+e:e}function x(e,t){return 0===(e+"").indexOf(t)?e.substring(t.length):e}function S(e){return!Array.isArray(e)&&"object"==typeof e&&null!==e}function R(e){return"function"==typeof e}function k(...e){return window.addEventListener(...e),()=>window.removeEventListener(...e)}function I({top:e=0,left:t=0,...n}={},o){o?document.documentElement.scrollIntoView?o.scrollIntoView({behavior:"smooth",...n}):window.scrollTo({top:o.offsetTop-e,behavior:"smooth",...n}):window.scrollTo({top:e,left:t,behavior:"smooth",...n})}function L(e,t=5e3){const n=new MutationObserver(e);n.observe(document.body,{childList:!0,subtree:!0});const o=()=>n.disconnect();return setTimeout(o,t),o}function N(e){if(Array.isArray(e))return e[e.length-1]=N(e[e.length-1]),e;if("object"==typeof e)return Object.entries(e).reduce(((e,[t,n])=>(e[t]=N(n),e)),{});if("true"===e||"false"===e)return"true"===e;if("null"===e)return null;if("undefined"!==e){if(""!==e&&!isNaN(Number(e))&&Number(e).toString()===e)return Number(e);if("separator"===b.array.format&&"string"==typeof e){const t=e.split(b.array.separator);return t.length>1?t:e}return e}}function C(e,t){const n=/(\[[^[\]]*])/g;let o=/(\[[^[\]]*])/.exec(e),r=o?e.slice(0,o.index):e,s=[];r&&s.push(r);let i=0;for(;(o=n.exec(e))&&i<b.nesting;)i++,s.push(o[1]);return o&&s.push(`[${e.slice(o.index)}]`),function(e,t){let n=t;for(let t=e.length-1;t>=0;--t){let o,r=e[t];if("[]"===r)o=[].concat(n);else{o={};const e="["===r.charAt(0)&&"]"===r.charAt(r.length-1)?r.slice(1,-1):r,t=parseInt(e,10);!isNaN(t)&&r!==e&&String(t)===e&&t>=0?(o=[],o[t]=b.convertTypes?N(n):n):o[e]=n}n=o}return n}(s,t)}function T(e={},t=""){return Object.entries(e).map((([e,n])=>"object"==typeof n?T(n,t?`${t}[${e}]`:e):`${t}[${e}]=${n}`)).join("&")}const P=B((function(e=""){return"string"==typeof e&&(e=x(e,"/").split("/")),Object.prototype.hasOwnProperty.call(e,"toString")?e:Object.defineProperty(e,"toString",{value(){return E(this.join("/"))},configurable:!1,writable:!1})})),U=B((function(e=""){return"string"==typeof e&&(e=function(e="",{decode:t=decodeURIComponent}={}){return e?e.replace("?","").replace(/\+/g," ").split("&").filter(Boolean).reduce(((e,n)=>{let[o,r]=n.split(/=(.*)/,2);o=t(o||""),r=t(r||"");let s=C(o,r);return e=Object.keys(s).reduce(((e,t)=>{const n=b.convertTypes?N(s[t]):s[t];return e[t]?Array.isArray(e[t])?e[t]=e[t].concat(n):Object.assign(e[t],n):e[t]=n,e}),e),e}),{}):{}}(e)),Object.prototype.hasOwnProperty.call(e,"toString")?e:Object.defineProperty(e,"toString",{value(){return E($(this),"?",!0)},configurable:!1,writable:!1})})),_=B((function(e=""){return E(A(e),"#",!0)}));function B(e){return(o,r)=>{let s=o&&o.toString();!Array.isArray(r)&&(r=[r]);const i=new Set(r),c=function(e){return(...t)=>{const n=[...e];return!(b.breakHooks?n.some((e=>!1===e(...t))):n.reduce(((e,n)=>!1===n(...t)||e),!1))}}(i),{subscribe:a,set:u}=t(o=e(o),(()=>()=>i.clear()));function l(t){(t=e(t)).toString()!==s&&!1!==c(t,o,e.name)&&(s=t.toString(),u(o=t))}return c(null,o,e.name),{subscribe:a,update(e){l(e(n(this)))},set(e){l(e)},hook:t=>(R(t)&&(i.add(t),t(null,o,e.name)),()=>i.delete(t))}}}const K=function(){const e=m().pathname;if(!e)return;return E(x(e,g()))}(),{search:z,hash:D}=m();let H=!0,M=!1,V=!1,W=0;const Z=P(K,J),q=U(z,J),X=_(D,J),Y=t({}),F=o([Z,q,X],(([t,n,o],r)=>{let s=!1;return e().then((()=>{s||r(t+n+o)})),()=>s=!0}),K+z+D),G=o(Z,(e=>j.bind(null,e.toString())));function J(){(b.scroll||b.focus)&&Y.update(((e={})=>(b.scroll&&(e._scroll={top:window.pageYOffset,left:window.pageXOffset}),b.focus&&(e._focus=document.activeElement.id),e)))}function Q(t,n){const o=t.indexOf("#")>=0?t.slice(t.indexOf("#")):"",r=document.activeElement;!S(n)&&(n={}),e().then((()=>function(e,t){function n(){return e?document.getElementById(e):document.activeElement!==t&&document.activeElement!==document.body?document.activeElement:document.querySelector("[autofocus]")}b.focus&&setTimeout((()=>{const e=n();if(e)return e.focus();const t=L((()=>{const e=n();e&&(t(),e.focus())})),o=document.body,r=o.getAttribute("tabindex");o.tabIndex=-1,o.focus({preventScroll:!0}),null!==r?o.setAttribute("tabindex",r):o.removeAttribute("tabindex"),getSelection().removeAllRanges()}))}(n._focus,r))).then((()=>O(n._scroll,o)))}if(d||l){const e=new Set;e.add(F.subscribe((e=>{H||M||!b.sideEffect||(a?history[V?"replaceState":"pushState"]({},null,y(e)):location.hash=y(e)),!M&&Q(e),!V&&W++,H=V=M=!1}))),a?(e.add(Y.subscribe((e=>{!H&&b.sideEffect&&history.replaceState(e,null,location.pathname+location.search+location.hash)}))),e.add(k("popstate",(e=>{M=!0,ee(location.href,e.state),Q(w(location.href),e.state)})))):e.add(k("hashchange",(()=>{if(M=!0,!b.hashbang&&!h)return X.set(location.hash);ee(location.hash),Q(w(location.hash))}))),e.add(k("beforeunload",(()=>{e.forEach((e=>e())),e.clear()}),!0))}function ee(t="",n={}){const{pathname:o,search:r,hash:s}=t instanceof URL?t:new URL(w(t),"file:");Z.set(o),q.set(r),X.set(s),e().then((()=>Y.set(n||{})))}function te(t){W>0&&d&&b.sideEffect?(history.back(),W--):e().then((()=>ee(t)))}function ne(t,n){e().then((()=>{V=!0,ee(t,n)}))}function oe(e){if(!e.target||e.ctrlKey||e.metaKey||e.altKey||e.shiftKey||e.button||1!==e.which||e.defaultPrevented)return;const t=function(e,t){for(;e&&e.nodeName.toLowerCase()!==t;)e=e.parentNode;return e&&e.nodeName.toLowerCase()===t?e:null}(e.target,"a");if(!t||t.target||t.hasAttribute("download")||t.hasAttribute("rel")&&t.getAttribute("rel").includes("external"))return;const n=t.getAttribute("href"),o=t.href;!n||0!==o.indexOf(location.origin)||r.test(n)||!b.hashbang&&!h&&n.startsWith("#")||(e.preventDefault(),ee(o,Object.assign({},t.dataset)))}function re(e){if(!e.target||e.defaultPrevented)return;const t=e.target,n=e.submitter||v(document.activeElement)&&document.activeElement;let o=t.action,r=t.method,s=t.target;if(n&&(n.hasAttribute("formaction")&&(o=n.formAction),n.hasAttribute("formmethod")&&(r=n.formMethod),n.hasAttribute("formtarget")&&(s=n.formTarget)),r&&"get"!==r.toLowerCase())return;if(s&&"_self"!==s.toLowerCase())return;const{pathname:c,hash:a}=new URL(o),u=[],l={},f=t.elements,d=f.length;for(let e=0;e<d;e++){const t=f[e];t.name&&!t.disabled&&(["checkbox","radio"].includes(t.type)&&!t.checked||v(t)&&t!==n||("hidden"!==t.type?u.push(`${t.name}=${t.value}`):l[t.name]=t.value))}let h=E(`${c}?${u.join("&")}${a}`);i&&h.match(/^\/[a-zA-Z]:\//)&&(h=h.replace(/^\/[a-zA-Z]:\//,"/")),e.preventDefault(),ee(h,l)}const se=function(e){return(o,r={})=>{if(o instanceof RegExp)throw new Error("Paramable does not support RegExp patterns.");let s;o=o.replace(/\/$/,"");const{subscribe:i}=t({},(t=>e.subscribe((e=>{var n;s=j(e.toString(),o,{blank:!0,...r}),t("object"!=typeof(n=s)||null===n?n:Object.create(Object.getPrototypeOf(n),Object.getOwnPropertyDescriptors(n)))}))));function c(t={}){Object.entries(s).some((([e,n])=>n!==t[e]))&&e.update((e=>{const n=r.loose?E(e.slice(o.split("/").length-1).join("/")):"";return function(e,t,{encode:n=encodeURIComponent}={}){return e.replace(/(\/|^)([:*][^/]*?)(\?)?(?=[/.]|$)/g,((e,o,r)=>(e=t["*"===r?"wild":r.substring(1)])?`/${n(e)}`:""))}(o+n,t)}))}return{get(){return n(this)},update(e){c(e(this.get()))},subscribe:i,set:c}}}(Z);export{te as back,oe as click,X as fragment,ee as goto,se as paramable,Z as path,G as pattern,b as prefs,q as query,ne as redirect,Y as state,re as submit,F as url};
//# sourceMappingURL=index.min.mjs.map