@wcstack/router 1.8.5 → 1.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,2 +1,2 @@
1
- const t={tagNames:{route:"wcs-route",router:"wcs-router",outlet:"wcs-outlet",layout:"wcs-layout",layoutOutlet:"wcs-layout-outlet",link:"wcs-link",head:"wcs-head",guardHandler:"wcs-guard-handler"},enableShadowRoot:!1,basenameFileExtensions:[".html"]};function e(t){if(null===t||"object"!=typeof t)return t;Object.freeze(t);for(const a of Object.keys(t))e(t[a]);return t}function a(t){if(null===t||"object"!=typeof t)return t;const e={};for(const n of Object.keys(t))e[n]=a(t[n]);return e}let n=null;const s=t;function i(){return n||(n=e(a(t))),n}function r(){return"undefined"!=typeof crypto&&crypto.randomUUID?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(t){const e=16*Math.random()|0;return("x"===t?e:3&e|8).toString(16)})}function o(t){throw new Error(`[@wcstack/router] ${t}`)}class l extends Error{fallbackPath;constructor(t,e){super(t),this.fallbackPath=e}}const h={int:{typeName:"int",pattern:/^-?\d+$/,parse(t){if(this.pattern.test(t))return parseInt(t,10)}},float:{typeName:"float",pattern:/^-?\d+(?:\.\d+)?$/,parse(t){if(this.pattern.test(t))return parseFloat(t)}},bool:{typeName:"bool",pattern:/^(true|false|0|1)$/,parse(t){if(this.pattern.test(t))return"true"===t||"1"===t}},uuid:{typeName:"uuid",pattern:/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,parse(t){if(this.pattern.test(t))return t}},slug:{typeName:"slug",pattern:/^[a-z0-9]+(?:-[a-z0-9]+)*$/,parse(t){if(this.pattern.test(t))return t}},isoDate:{typeName:"isoDate",pattern:/^\d{4}-\d{2}-\d{2}$/,parse(t){if(!this.pattern.test(t))return;const[e,a,n]=t.split("-").map(Number),s=new Date(e,a-1,n);return s.getFullYear()===e&&s.getMonth()===a-1&&s.getDate()===n?s:void 0}},any:{typeName:"any",pattern:/^.+$/,parse(t){if(this.pattern.test(t))return t}}},u={static:2,param:1,"catch-all":0};class c extends EventTarget{static wcBindable={protocol:"wc-bindable",version:1,properties:[{name:"params",event:"wcs-route:params-changed"},{name:"typedParams",event:"wcs-route:params-changed",getter:t=>t.detail.typedParams},{name:"active",event:"wcs-route:active-changed"}]};_target;_parentCore=null;_path="";_name="";_isFallbackRoute=!1;_segmentInfos=[];_absoluteSegmentInfos;_paramNames;_absoluteParamNames;_weight;_absoluteWeight;_segmentCount;_params={};_typedParams={};_active=!1;_hasGuard=!1;_guardHandler=null;_guardFallbackPath="";_waitForSetGuardHandler=null;_resolveSetGuardHandler=null;constructor(t){super(),this._target=t??this}get parentCore(){return this._parentCore}set parentCore(t){this._parentCore=t}get path(){return this._path}get name(){return this._name}get isFallbackRoute(){return this._isFallbackRoute}get isRelative(){return!this._path.startsWith("/")}get segmentInfos(){return this._segmentInfos}_checkParentCore(t,e){return this._isFallbackRoute||(this.isRelative&&!this._parentCore&&o(`${s.tagNames.route} is relative but has no parent route.`),!this.isRelative&&this._parentCore&&o(`${s.tagNames.route} is absolute but has a parent route.`)),this.isRelative&&this._parentCore?t(this._parentCore):e()}get absolutePath(){return this._checkParentCore(t=>{const e=t.absolutePath;return e.endsWith("/")?e+this._path:e+"/"+this._path},()=>this._path)}get absoluteSegmentInfos(){return void 0===this._absoluteSegmentInfos&&(this._absoluteSegmentInfos=this._checkParentCore(t=>[...t.absoluteSegmentInfos,...this._segmentInfos],()=>[...this._segmentInfos])),this._absoluteSegmentInfos}get params(){return this._params}get typedParams(){return this._typedParams}get active(){return this._active}get paramNames(){if(void 0===this._paramNames){const t=[];for(const e of this._segmentInfos)e.paramName&&t.push(e.paramName);this._paramNames=t}return this._paramNames}get absoluteParamNames(){return void 0===this._absoluteParamNames&&(this._absoluteParamNames=this._checkParentCore(t=>[...t.absoluteParamNames,...this.paramNames],()=>[...this.paramNames])),this._absoluteParamNames}get weight(){if(void 0===this._weight){let t=0;for(const e of this._segmentInfos)t+=u[e.type];this._weight=t}return this._weight}get absoluteWeight(){return void 0===this._absoluteWeight&&(this._absoluteWeight=this._checkParentCore(t=>t.absoluteWeight+this.weight,()=>this.weight)),this._absoluteWeight}get segmentCount(){if(void 0===this._segmentCount){let t=0;for(const e of this._segmentInfos)"catch-all"!==e.type&&t++;this._segmentCount=""===this._path?0:t}return this._segmentCount}get absoluteSegmentCount(){return this._checkParentCore(t=>t.absoluteSegmentCount+this.segmentCount,()=>this.segmentCount)}parsePath(t,e={}){this._path=t,this._name=e.name||"",this._isFallbackRoute=e.isFallback||!1,e.isIndex&&this._segmentInfos.push({type:"static",segmentText:"",paramName:null,pattern:/^$/,isIndex:!0});const a=t.split("/");for(let t=0;t<a.length;t++){const n=a[t];if(!(""===n&&t===a.length-1&&t>0)){if("*"===n){this._segmentInfos.push({type:"catch-all",segmentText:n,paramName:"*",pattern:new RegExp("^(.*)$")});break}if(n.startsWith(":")){const t=n.match(/^:([^()]+)(\(([^)]+)\))?$/);let e,a="any";t?(e=t[1],t[3]&&Object.keys(h).includes(t[3])&&(a=t[3])):e=n.substring(1),this._segmentInfos.push({type:"param",segmentText:n,paramName:e,pattern:new RegExp("^([^\\/]+)$"),paramType:a})}else""===n&&e.isIndex||this._segmentInfos.push({type:"static",segmentText:n,paramName:null,pattern:new RegExp(`^${n}$`)})}}this._hasGuard=e.hasGuard||!1,this._hasGuard&&(this._guardFallbackPath=e.guardFallback||"/",this._waitForSetGuardHandler=new Promise(t=>{this._resolveSetGuardHandler=t}))}setParams(t,e){this._params=t,this._typedParams=e,this._active=!0,this._target.dispatchEvent(new CustomEvent("wcs-route:params-changed",{detail:{params:t,typedParams:e},bubbles:!0}))}clearParams(){this._params={},this._typedParams={},this._active=!1}shouldChange(t){for(const e of this.paramNames)if(this._params[e]!==t[e])return!0;return!1}get guardHandler(){return this._guardHandler||o(`${s.tagNames.route} has no guardHandler.`),this._guardHandler}set guardHandler(t){this._resolveSetGuardHandler?.(),this._guardHandler=t}async guardCheck(t){if(this._hasGuard&&this._waitForSetGuardHandler&&await this._waitForSetGuardHandler,this._guardHandler){const e=t.path,a=t.lastPath;if(!await this._guardHandler(e,a))throw new l("Navigation cancelled by guard.",this._guardFallbackPath)}}}class d extends HTMLElement{static wcBindable=c.wcBindable;_core;_routeParentNode=null;_routeChildNodes=[];_routerNode=null;_uuid=r();_placeHolder=document.createComment(`@@route:${this._uuid}`);_childNodeArray;_childIndex=0;_initialized=!1;constructor(){super(),this._core=new c(this)}get routeParentNode(){return this._routeParentNode}get routeChildNodes(){return this._routeChildNodes}get routerNode(){return this._routerNode||o(`${s.tagNames.route} has no routerNode.`),this._routerNode}get uuid(){return this._uuid}get placeHolder(){return this._placeHolder}get childNodeArray(){return void 0===this._childNodeArray&&(this._childNodeArray=Array.from(this.childNodes)),this._childNodeArray}get routes(){return this.routeParentNode?this.routeParentNode.routes.concat(this):[this]}get childIndex(){return this._childIndex}get path(){return this._core.path}get name(){return this._core.name}get isRelative(){return this._core.isRelative}get absolutePath(){return this._core.absolutePath}get segmentInfos(){return this._core.segmentInfos}get absoluteSegmentInfos(){return this._core.absoluteSegmentInfos}get params(){return this._core.params}get typedParams(){return this._core.typedParams}get paramNames(){return this._core.paramNames}get absoluteParamNames(){return this._core.absoluteParamNames}get weight(){return this._core.weight}get absoluteWeight(){return this._core.absoluteWeight}get segmentCount(){return this._core.segmentCount}get absoluteSegmentCount(){return this._core.absoluteSegmentCount}get fullpath(){return this.absolutePath}get guardHandler(){return this._core.guardHandler}set guardHandler(t){this._core.guardHandler=t}setParams(t,e){this._core.setParams(t,e)}clearParams(){this._core.clearParams()}shouldChange(t){return this._core.shouldChange(t)}async guardCheck(t){return this._core.guardCheck(t)}testAncestorNode(t){let e=this._routeParentNode;for(;e;){if(e===t)return!0;e=e.routeParentNode}return!1}initialize(t,e){if(this._initialized)return;let a;this._initialized=!0;let n=!1,i=!1;this.hasAttribute("path")?a=this.getAttribute("path")||"":this.hasAttribute("index")?(a="",n=!0):this.hasAttribute("fallback")?(a="",i=!0):o(`${s.tagNames.route} should have a "path" or "index" attribute.`),this._routerNode=t,this._routeParentNode=e;const r=e||t;r.routeChildNodes.push(this),this._childIndex=r.routeChildNodes.length-1,i&&(e&&o(`${s.tagNames.route} with fallback attribute must be a direct child of ${s.tagNames.router}.`),t.fallbackRoute&&o(`${s.tagNames.router} can have only one fallback route.`),t.fallbackRoute=this),e&&(this._core.parentCore=e._core),this._core.parsePath(a,{isIndex:n,isFallback:i,hasGuard:this.hasAttribute("guard"),guardFallback:this.getAttribute("guard"),name:this.getAttribute("name")||""}),this.setAttribute("fullpath",this.absolutePath)}}const m=new Map;class p extends HTMLElement{_uuid=r();_initialized=!1;constructor(){super()}async _loadTemplateFromSource(t){try{const e=await fetch(t);e.ok||o(`${s.tagNames.layout} failed to fetch layout from source: ${t}, status: ${e.status}`);const a=await e.text();return m.set(t,a),a}catch(e){o(`${s.tagNames.layout} failed to load layout from source: ${t}, error: ${e}`)}}_loadTemplateFromDocument(t){const e=document.getElementById(`${t}`);return e&&e instanceof HTMLTemplateElement?e.innerHTML:null}async loadTemplate(){const t=this.getAttribute("src"),e=this.getAttribute("layout");t&&e&&console.warn(`${s.tagNames.layout} have both "src" and "layout" attributes.`);const a=document.createElement("template");if(t)m.has(t)?a.innerHTML=m.get(t)||"":(a.innerHTML=await this._loadTemplateFromSource(t)||"",m.set(t,a.innerHTML));else if(e){const t=this._loadTemplateFromDocument(e);t?a.innerHTML=t:console.warn(`${s.tagNames.layout} could not find template with id "${e}".`)}return a}get uuid(){return this._uuid}get enableShadowRoot(){return!!this.hasAttribute("enable-shadow-root")||!this.hasAttribute("disable-shadow-root")&&s.enableShadowRoot}get name(){return this.getAttribute("name")||""}_initialize(){this._initialized=!0}connectedCallback(){this._initialized||this._initialize()}}class g extends HTMLElement{_routesNode=null;_lastRoutes=[];_initialized=!1;constructor(){super()}get routesNode(){return this._routesNode||o(`${s.tagNames.outlet} has no routesNode.`),this._routesNode}set routesNode(t){this._routesNode=t}get rootNode(){return this.shadowRoot?this.shadowRoot:this}get lastRoutes(){return this._lastRoutes}set lastRoutes(t){this._lastRoutes=[...t]}_initialize(){s.enableShadowRoot&&this.attachShadow({mode:"open"}),this._initialized=!0}connectedCallback(){this._initialized||this._initialize()}}const _=new Set(["props","states","attr",""]);function f(t,e,a){for(const[n,s]of Object.entries(e))switch(a){case"props":t.props={...t.props,[n]:s};break;case"states":t.states={...t.states,[n]:s};break;case"attr":t.setAttribute(n,s);break;case"":t[n]=s}}function b(t,e){t.hasAttribute("data-bind")||o(`${t.tagName} has no 'data-bind' attribute.`);const a=t.getAttribute("data-bind")||"";_.has(a)||o(`${t.tagName} has invalid 'data-bind' attribute: ${a}`);const n=a,s=function(t){const e=t.tagName.toLowerCase();if(e.includes("-"))return e;const a=t.getAttribute("is");return a&&a.includes("-")?a:null}(t);s&&void 0===customElements.get(s)?customElements.whenDefined(s).then(()=>{t.isConnected&&f(t,e,n)}).catch(()=>{o(`Failed to define custom element: ${s}`)}):f(t,e,n)}class y extends HTMLElement{_layout=null;_initialized=!1;_layoutChildNodes=[];constructor(){super()}get layout(){return this._layout||o(`${s.tagNames.layoutOutlet} has no layout.`),this._layout}set layout(t){this._layout=t,this.setAttribute("name",t.name)}get name(){return this.layout.name}async _initialize(){this._initialized=!0,this.layout.enableShadowRoot&&this.attachShadow({mode:"open"});const t=await this.layout.loadTemplate();if(this.shadowRoot){this.shadowRoot.appendChild(t.content.cloneNode(!0));for(const t of Array.from(this.layout.childNodes))this._layoutChildNodes.push(t),this.appendChild(t)}else{const e=t.content.cloneNode(!0),a=new Map;e.querySelectorAll("slot").forEach(t=>{const e=t.getAttribute("name")||"";a.has(e)?console.warn(`${s.tagNames.layoutOutlet} duplicate slot name "${e}" in layout template.`):a.set(e,t)});const n=new Map,i=document.createDocumentFragment();for(const t of Array.from(this.layout.childNodes)){if(this._layoutChildNodes.push(t),t instanceof Element){const e=t.getAttribute("slot")||"";if(e.length>0&&a.has(e)){n.has(e)||n.set(e,document.createDocumentFragment()),n.get(e)?.appendChild(t);continue}}i.appendChild(t)}for(const[t,e]of a){const a=n.get(t);a&&e.replaceWith(a)}const r=a.get("");r&&r.replaceWith(i),this.appendChild(e)}}async connectedCallback(){this._initialized||await this._initialize()}assignParams(t){for(const e of this._layoutChildNodes)e instanceof Element&&(e.querySelectorAll("[data-bind]").forEach(e=>{b(e,t)}),e.hasAttribute("data-bind")&&b(e,t))}}function N(){return document.createElement(s.tagNames.layoutOutlet)}function w(t,e){(async function(t){let e=null;const a=t.text+"\n//# sourceURL=wcs-guard-handler\n";if("function"==typeof URL.createObjectURL){const t=new Blob([a],{type:"application/javascript"}),n=URL.createObjectURL(t);try{e=await import(n)}catch{}finally{URL.revokeObjectURL(n)}}if(!e){const t=btoa(String.fromCodePoint(...(new TextEncoder).encode(a)));e=await import(`data:application/javascript;base64,${t}`)}return e&&"function"==typeof e.default?e.default:null})(t).then(t=>{t&&(e.guardHandler=t)})}function v(t,e){let a=t.get(e.absolutePath);a||(a=[]);for(const t of a)if(!e.testAncestorNode(t)){console.warn(`Duplicate route path detected: '${e.absolutePath}' (defined as '${e.path}')`);break}a.push(e),1===a.length&&t.set(e.absolutePath,a)}async function C(t,e,a,n,i){const r=a.length>0?a[a.length-1]:null,o=document.createDocumentFragment(),l=Array.from(e.childNodes);for(const e of l)if(e.nodeType===Node.ELEMENT_NODE){let l=e,h=e;const u=h.tagName.toLowerCase();if(u===s.tagNames.route){const e=document.createDocumentFragment();for(const t of Array.from(h.childNodes))e.appendChild(t);const s=document.importNode(h,!0);customElements.upgrade(s),s.appendChild(e);const o=s;o.initialize(t,r),v(i,o),a.push(o),n.set(o.uuid,o),l=o.placeHolder,h=o}else{if(u===s.tagNames.guardHandler){if(a.length>0){const t=a[a.length-1],e=h.querySelector('script[type="module"]');e&&w(e,t)}continue}if(u===s.tagNames.layout){const t=document.createDocumentFragment();for(const e of Array.from(h.childNodes))t.appendChild(e);const e=document.importNode(h,!0);customElements.upgrade(e),e.appendChild(t);const a=e,n=N();n.layout=a,l=n,h=e}}const c=await C(t,h,a,n,i);h.innerHTML="",h.appendChild(c),o.appendChild(l)}else o.appendChild(e);return o}async function E(t){const e=new Map,a=new Map;return await C(t,t.template.content,[],e,a)}function P(t,e,a,n,s,i){const r=a.concat(e),o=function(t,e,a){const n={},s={};let i=!0,r=!1,o=0,l=0;for(;o<t.absoluteSegmentInfos.length;){const e=t.absoluteSegmentInfos[o];if(e.isIndex){o++;continue}if(0===o&&""===e.segmentText&&"static"===e.type){o++;continue}const u=a[l];if(void 0===u){i=!1;break}let c=!1;if("param"===e.type){const t=e.paramType||"any",a=h[t].parse(u);void 0!==a&&(e.paramName&&(n[e.paramName]=u,s[e.paramName]=a),c=!0)}else c=null!==e.pattern.exec(u);if(!c){i=!1;break}if("catch-all"===e.type){const t=a.slice(l).join("/");n["*"]=t,s["*"]=t,r=!0;break}o++,l++}let u=!1;return i&&(r||o===t.absoluteSegmentInfos.length&&l===a.length||o===t.absoluteSegmentInfos.length&&l===a.length-1&&""===a.at(-1))&&(u=!0),u?{path:e,routes:t.routes,params:n,typedParams:s,lastPath:""}:null}(e,n,s);o&&i.push(o);for(const a of e.routeChildNodes)P(t,a,r,n,s,i)}function k(t){t.clearParams();for(const e of t.childNodeArray)e.parentNode?.removeChild(e)}function A(t,e){const a={},n={};for(const s of t.paramNames)a[s]=e.params[s],n[s]=e.typedParams[s];t.setParams(a,n);const i=t.placeHolder.parentNode,r=t.placeHolder.nextSibling;for(const e of t.childNodeArray){if(e.nodeType===Node.ELEMENT_NODE){const a=e;a.querySelectorAll("[data-bind]").forEach(e=>{b(e,t.typedParams)}),a.hasAttribute("data-bind")&&b(a,t.typedParams),a.querySelectorAll(s.tagNames.layoutOutlet).forEach(e=>{e.assignParams(t.typedParams)}),a.tagName.toLowerCase()===s.tagNames.layoutOutlet&&a.assignParams(t.typedParams)}r?i?.insertBefore(e,r):i?.appendChild(e)}return!0}async function x(t,e,a,n){const i=t.basename;let r=a;""!==i&&(a===i?r="":a.startsWith(i+"/")&&(r=a.slice(i.length)));const l=""===r?"/":r;let h=function(t,e){const a=[],n=t.routeChildNodes,s=[],i=e.split("/"),r=i.filter((t,e)=>!(0===e&&""===t||e===i.length-1&&""===t&&i.length>1));for(const i of n)P(t,i,a,e,r,s);return s.sort((t,e)=>{const a=t.routes.at(-1),n=e.routes.at(-1),s=a.absoluteSegmentCount-n.absoluteSegmentCount;if(0!==s)return-s;const i=a.absoluteWeight-n.absoluteWeight;return 0!==i?-i:a.childIndex-n.childIndex}),s.length>0?s[0]:null}(t,l);h||(t.fallbackRoute?h={routes:[t.fallbackRoute],params:{},typedParams:{},path:l,lastPath:n}:o(`${s.tagNames.router} No route matched for path: ${l}`)),h.lastPath=n;const u=e.lastRoutes;await async function(t,e,a){const n=new Set(e.routes);for(const t of a)n.has(t)||k(t);try{for(const t of e.routes)await t.guardCheck(e)}catch(e){const a=e;if("fallbackPath"in a){const e=a;return console.warn(`Navigation cancelled: ${a.message}. Redirecting to ${e.fallbackPath}`),void queueMicrotask(()=>{t.navigate(e.fallbackPath)})}throw e}const s=new Set(a);let i=!1;for(const t of e.routes)(!s.has(t)||t.shouldChange(e.params)||i)&&(i=A(t,e))}(t,h,u),t.path=l,e.lastRoutes=h.routes}function S(){const t=window.navigation;return t?"function"!=typeof t.addEventListener||"function"!=typeof t.removeEventListener?null:t:null}class $ extends HTMLElement{static wcBindable={protocol:"wc-bindable",version:1,properties:[{name:"navigateUrl",event:"wcs-router:navigate-url-changed"},{name:"path",event:"wcs-router:path-changed"}]};static _instance=null;_outlet=null;_template=null;_routeChildNodes=[];_basename="";_path="";_initialized=!1;_fallbackRoute=null;_listeningPopState=!1;_navigateUrl=null;constructor(){super(),$._instance&&o(`${s.tagNames.router} can only be instantiated once.`),$._instance=this}_normalizePathname(t){let e=t||"/";e.startsWith("/")||(e="/"+e),e=e.replace(/\/{2,}/g,"/");const a=s.basenameFileExtensions;if(a.length>0){const t=new RegExp(`\\/[^/]+(?:${a.map(t=>t.replace(/\./g,"\\.")).join("|")})$`,"i");e=e.replace(t,"")}return""===e&&(e="/"),e.length>1&&e.endsWith("/")&&(e=e.slice(0,-1)),e}_normalizeBasename(t){let e=t||"";if(!e)return"";e.startsWith("/")||(e="/"+e),e=e.replace(/\/{2,}/g,"/");const a=s.basenameFileExtensions;if(a.length>0){const t=new RegExp(`\\/[^/]+(?:${a.map(t=>t.replace(/\./g,"\\.")).join("|")})$`,"i");e=e.replace(t,"")}return e.length>1&&e.endsWith("/")&&(e=e.slice(0,-1)),"/"===e?"":e}_joinInternalPath(t,e){const a=this._normalizeBasename(t);let n=e.startsWith("/")?e:"/"+e;return n=this._normalizePathname(n),a?"/"===n?a+"/":a+n:n}_notifyLocationChange(){window.dispatchEvent(new CustomEvent("wcs:navigate"))}_getBasename(){let t=new URL(document.baseURI).pathname||"/";return"/"===t?"":this._normalizeBasename(t)}static get instance(){return $._instance||o(`${s.tagNames.router} has not been instantiated.`),$._instance}static navigate(t){$.instance.navigate(t)}get basename(){return this._basename}_getOutlet(){let t=document.querySelector(s.tagNames.outlet);return t||(t=document.createElement(s.tagNames.outlet),document.body.appendChild(t)),t}_getTemplate(){return this.querySelector("template")}get outlet(){return this._outlet||o(`${s.tagNames.router} has no outlet.`),this._outlet}get template(){return this._template||o(`${s.tagNames.router} has no template.`),this._template}get routeChildNodes(){return this._routeChildNodes}get path(){return this._path}set path(t){const e=this._path!==t;this._path=t,e&&this.dispatchEvent(new CustomEvent("wcs-router:path-changed",{detail:t,bubbles:!0}))}get fallbackRoute(){return this._fallbackRoute}set fallbackRoute(t){this._fallbackRoute=t}get navigateUrl(){return this._navigateUrl}set navigateUrl(t){null!=t&&""!==t&&(this._navigateUrl=t,this.navigate(t).then(()=>{this._navigateUrl=null,this.dispatchEvent(new CustomEvent("wcs-router:navigate-url-changed",{detail:null,bubbles:!0}))}))}async navigate(t){const e=this._joinInternalPath(this._basename,t),a=S();a?.navigate?a.navigate(e):(history.pushState(null,"",e),await x(this,this.outlet,e,this._path),this._notifyLocationChange())}_onNavigateFunc(t){if(!t.canIntercept||t.hashChange||null!==t.downloadRequest)return;const e=this;t.intercept({handler:async()=>{const a=new URL(t.destination.url),n=e._normalizePathname(a.pathname);await x(e,e.outlet,n,e.path)}})}_onNavigate=this._onNavigateFunc.bind(this);_onPopState=async()=>{const t=this._normalizePathname(window.location.pathname);await x(this,this.outlet,t,this._path),this._notifyLocationChange()};async _initialize(){this._initialized=!0,this._basename=this._normalizeBasename(this.getAttribute("basename")||this._getBasename()||"");const t=null!==document.querySelector("base[href]"),e=new URL(window.location.href);""!==this._basename||t||"/"===e.pathname||o(`${s.tagNames.router} basename is empty, but current path is not "/".`),this._outlet=this._getOutlet(),this._outlet.routesNode=this,this._template=this._getTemplate(),this._template||o(`${s.tagNames.router} should have a <template> child element.`);const a=await E(this);this._outlet.rootNode.appendChild(a),0===this.routeChildNodes.length&&o(`${s.tagNames.router} has no route definitions.`);const n=this._normalizePathname(window.location.pathname);await x(this,this.outlet,n,this._path),this._notifyLocationChange()}async connectedCallback(){this._initialized||await this._initialize(),S()?.addEventListener("navigate",this._onNavigate),S()?.addEventListener||this._listeningPopState||(window.addEventListener("popstate",this._onPopState),this._listeningPopState=!0)}disconnectedCallback(){S()?.removeEventListener("navigate",this._onNavigate),this._listeningPopState&&(window.removeEventListener("popstate",this._onPopState),this._listeningPopState=!1),$._instance===this&&($._instance=null)}}class R extends HTMLElement{static get observedAttributes(){return["to"]}_childNodeArray=[];_uuid=r();_path="";_router=null;_anchorElement=null;_initialized=!1;_onClick;constructor(){super()}get uuid(){return this._uuid}get router(){if(this._router)return this._router;const t=document.querySelector(s.tagNames.router);if(t)return this._router=t;o(`${s.tagNames.link} is not connected to a router.`)}_initialize(){this.style.display="none",this._childNodeArray=Array.from(this.childNodes),this._path=this.getAttribute("to")||"",this._initialized=!0}_normalizePathname(t){let e=t||"/";return e.startsWith("/")||(e="/"+e),e=e.replace(/\/{2,}/g,"/"),e.length>1&&e.endsWith("/")&&(e=e.slice(0,-1)),e}_joinInternalPath(t,e){const a=(t||"").replace(/\/{2,}/g,"/").replace(/\/$/,""),n=e.startsWith("/")?e:"/"+e,s=this._normalizePathname(n);return a?"/"===s?a+"/":a+s:s}_setAnchorHref(t,e){if(e.startsWith("/"))t.href=this._joinInternalPath(this.router.basename,e);else try{t.href=new URL(e).toString()}catch{o(`[${s.tagNames.link}] Invalid URL in 'to' attribute: ${e}`)}}connectedCallback(){this._initialized||this._initialize();const t=this.parentNode;if(!t)return;const e=this.nextSibling,a=document.createElement("a");this._setAnchorHref(a,this._path);for(const t of this._childNodeArray)a.appendChild(t);e?t.insertBefore(a,e):t.appendChild(a),this._anchorElement=a,S()?.addEventListener("currententrychange",this._updateActiveState),window.addEventListener("wcs:navigate",this._updateActiveState),window.addEventListener("popstate",this._updateActiveState),this._path.startsWith("/")&&!S()?.navigate&&(this._onClick=async t=>{t.defaultPrevented||0===t.button&&(t.metaKey||t.ctrlKey||t.shiftKey||t.altKey||(t.preventDefault(),await this.router.navigate(this._path),this._updateActiveState()))},a.addEventListener("click",this._onClick)),this._updateActiveState()}disconnectedCallback(){S()?.removeEventListener("currententrychange",this._updateActiveState),window.removeEventListener("wcs:navigate",this._updateActiveState),window.removeEventListener("popstate",this._updateActiveState),this._anchorElement&&(this._onClick&&(this._anchorElement.removeEventListener("click",this._onClick),this._onClick=void 0),this._anchorElement.remove(),this._anchorElement=null);for(const t of this._childNodeArray)t.parentNode?.removeChild(t)}attributeChangedCallback(t,e,a){"to"===t&&e!==a&&(this._path=a||"",this._anchorElement&&(this._setAnchorHref(this._anchorElement,this._path),this._updateActiveState()))}_updateActiveState=()=>{const t=this._normalizePathname(new URL(window.location.href).pathname),e=this._normalizePathname(this._path.startsWith("/")?this._joinInternalPath(this.router.basename,this._path):this._path);this._anchorElement&&(t===e?this._anchorElement.classList.add("active"):this._anchorElement.classList.remove("active"))};get anchorElement(){return this._anchorElement}}const H=[],L=new Map;let z=!1;class I extends HTMLElement{_initialized=!1;_childElementArray=[];constructor(){super(),this.style.display="none"}_initialize(){if(!this._initialized){this._initialized=!0,this._childElementArray=Array.from(this.children);for(const t of this._childElementArray)this.removeChild(t)}}connectedCallback(){this._initialize(),z||(this._captureInitialHead(),z=!0),H.push(this),this._reapplyHead()}disconnectedCallback(){const t=H.indexOf(this);-1!==t&&H.splice(t,1),this._reapplyHead()}get childElementArray(){return this._initialized||o("Head component is not initialized yet."),this._childElementArray}_getKey(t){const e=t.tagName.toLowerCase();if("title"===e)return"title";if("meta"===e){return`meta:${t.getAttribute("name")||""}:${t.getAttribute("property")||""}:${t.getAttribute("http-equiv")||""}:${t.hasAttribute("charset")?"charset":""}:${t.getAttribute("media")||""}`}if("link"===e){return`link:${t.getAttribute("rel")||""}:${t.getAttribute("href")||""}:${t.getAttribute("media")||""}`}return"base"===e?"base":`${e}:${t.outerHTML.slice(0,100)}`}_findInHead(t){const e=document.head;for(const a of Array.from(e.children))if(this._getKey(a)===t)return a;return null}_captureInitialHead(){const t=document.head;for(const e of Array.from(t.children)){const t=this._getKey(e);L.has(t)||L.set(t,e.cloneNode(!0))}}_reapplyHead(){const t=new Set;for(const e of H)for(const a of e._childElementArray)t.add(this._getKey(a));for(const e of L.keys())t.add(e);for(const e of Array.from(document.head.children))t.add(this._getKey(e));for(const e of t){let t=null;for(let a=H.length-1;a>=0;a--){const n=H[a];for(const a of n._childElementArray)if(this._getKey(a)===e){t=a.cloneNode(!0);break}if(t)break}if(!t&&L.has(e)){t=L.get(e).cloneNode(!0)}const a=this._findInHead(e);t?a?a.replaceWith(t):document.head.appendChild(t):a?.remove()}}}function T(){customElements.get(s.tagNames.layout)||customElements.define(s.tagNames.layout,p),customElements.get(s.tagNames.layoutOutlet)||customElements.define(s.tagNames.layoutOutlet,y),customElements.get(s.tagNames.outlet)||customElements.define(s.tagNames.outlet,g),customElements.get(s.tagNames.route)||customElements.define(s.tagNames.route,d),customElements.get(s.tagNames.router)||customElements.define(s.tagNames.router,$),customElements.get(s.tagNames.link)||customElements.define(s.tagNames.link,R),customElements.get(s.tagNames.head)||customElements.define(s.tagNames.head,I)}function F(e){var a;e&&((a=e).tagNames&&Object.assign(t.tagNames,a.tagNames),"boolean"==typeof a.enableShadowRoot&&(t.enableShadowRoot=a.enableShadowRoot),Array.isArray(a.basenameFileExtensions)&&(t.basenameFileExtensions=a.basenameFileExtensions),n=null),T()}export{d as Route,c as RouteCore,$ as Router,F as bootstrapRouter,i as getConfig};
1
+ const t={tagNames:{route:"wcs-route",router:"wcs-router",outlet:"wcs-outlet",layout:"wcs-layout",layoutOutlet:"wcs-layout-outlet",link:"wcs-link",head:"wcs-head",guardHandler:"wcs-guard-handler"},enableShadowRoot:!1,basenameFileExtensions:[".html"]};function e(t){if(null===t||"object"!=typeof t)return t;Object.freeze(t);for(const a of Object.keys(t))e(t[a]);return t}function a(t){if(null===t||"object"!=typeof t)return t;const e={};for(const s of Object.keys(t))e[s]=a(t[s]);return e}let s=null;const n=t;function i(){return s||(s=e(a(t))),s}function r(){return"undefined"!=typeof crypto&&crypto.randomUUID?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(t){const e=16*Math.random()|0;return("x"===t?e:3&e|8).toString(16)})}function o(t){throw new Error(`[@wcstack/router] ${t}`)}class l extends Error{fallbackPath;constructor(t,e){super(t),this.fallbackPath=e}}const h={int:{typeName:"int",pattern:/^-?\d+$/,parse(t){if(this.pattern.test(t))return parseInt(t,10)}},float:{typeName:"float",pattern:/^-?\d+(?:\.\d+)?$/,parse(t){if(this.pattern.test(t))return parseFloat(t)}},bool:{typeName:"bool",pattern:/^(true|false|0|1)$/,parse(t){if(this.pattern.test(t))return"true"===t||"1"===t}},uuid:{typeName:"uuid",pattern:/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,parse(t){if(this.pattern.test(t))return t}},slug:{typeName:"slug",pattern:/^[a-z0-9]+(?:-[a-z0-9]+)*$/,parse(t){if(this.pattern.test(t))return t}},isoDate:{typeName:"isoDate",pattern:/^\d{4}-\d{2}-\d{2}$/,parse(t){if(!this.pattern.test(t))return;const[e,a,s]=t.split("-").map(Number),n=new Date(e,a-1,s);return n.getFullYear()===e&&n.getMonth()===a-1&&n.getDate()===s?n:void 0}},any:{typeName:"any",pattern:/^.+$/,parse(t){if(this.pattern.test(t))return t}}},u={static:2,param:1,"catch-all":0};class c extends EventTarget{static wcBindable={protocol:"wc-bindable",version:1,properties:[{name:"params",event:"wcs-route:params-changed"},{name:"typedParams",event:"wcs-route:params-changed",getter:t=>t.detail.typedParams},{name:"active",event:"wcs-route:active-changed"}]};_target;_parentCore=null;_path="";_name="";_isFallbackRoute=!1;_segmentInfos=[];_absoluteSegmentInfos;_paramNames;_absoluteParamNames;_weight;_absoluteWeight;_segmentCount;_params={};_typedParams={};_active=!1;_hasGuard=!1;_guardHandler=null;_guardFallbackPath="";_waitForSetGuardHandler=null;_resolveSetGuardHandler=null;constructor(t){super(),this._target=t??this}get parentCore(){return this._parentCore}set parentCore(t){this._parentCore=t}get path(){return this._path}get name(){return this._name}get isFallbackRoute(){return this._isFallbackRoute}get isRelative(){return!this._path.startsWith("/")}get segmentInfos(){return this._segmentInfos}_checkParentCore(t,e){return this._isFallbackRoute||(this.isRelative&&!this._parentCore&&o(`${n.tagNames.route} is relative but has no parent route.`),!this.isRelative&&this._parentCore&&o(`${n.tagNames.route} is absolute but has a parent route.`)),this.isRelative&&this._parentCore?t(this._parentCore):e()}get absolutePath(){return this._checkParentCore(t=>{const e=t.absolutePath;return e.endsWith("/")?e+this._path:e+"/"+this._path},()=>this._path)}get absoluteSegmentInfos(){return void 0===this._absoluteSegmentInfos&&(this._absoluteSegmentInfos=this._checkParentCore(t=>[...t.absoluteSegmentInfos,...this._segmentInfos],()=>[...this._segmentInfos])),this._absoluteSegmentInfos}get params(){return this._params}get typedParams(){return this._typedParams}get active(){return this._active}get paramNames(){if(void 0===this._paramNames){const t=[];for(const e of this._segmentInfos)e.paramName&&t.push(e.paramName);this._paramNames=t}return this._paramNames}get absoluteParamNames(){return void 0===this._absoluteParamNames&&(this._absoluteParamNames=this._checkParentCore(t=>[...t.absoluteParamNames,...this.paramNames],()=>[...this.paramNames])),this._absoluteParamNames}get weight(){if(void 0===this._weight){let t=0;for(const e of this._segmentInfos)t+=u[e.type];this._weight=t}return this._weight}get absoluteWeight(){return void 0===this._absoluteWeight&&(this._absoluteWeight=this._checkParentCore(t=>t.absoluteWeight+this.weight,()=>this.weight)),this._absoluteWeight}get segmentCount(){if(void 0===this._segmentCount){let t=0;for(const e of this._segmentInfos)"catch-all"!==e.type&&t++;this._segmentCount=""===this._path?0:t}return this._segmentCount}get absoluteSegmentCount(){return this._checkParentCore(t=>t.absoluteSegmentCount+this.segmentCount,()=>this.segmentCount)}parsePath(t,e={}){this._path=t,this._name=e.name||"",this._isFallbackRoute=e.isFallback||!1,e.isIndex&&this._segmentInfos.push({type:"static",segmentText:"",paramName:null,pattern:/^$/,isIndex:!0});const a=t.split("/");for(let t=0;t<a.length;t++){const s=a[t];if(!(""===s&&t===a.length-1&&t>0)){if("*"===s){this._segmentInfos.push({type:"catch-all",segmentText:s,paramName:"*",pattern:new RegExp("^(.*)$")});break}if(s.startsWith(":")){const t=s.match(/^:([^()]+)(\(([^)]+)\))?$/);let e,a="any";t?(e=t[1],t[3]&&Object.keys(h).includes(t[3])&&(a=t[3])):e=s.substring(1),this._segmentInfos.push({type:"param",segmentText:s,paramName:e,pattern:new RegExp("^([^\\/]+)$"),paramType:a})}else""===s&&e.isIndex||this._segmentInfos.push({type:"static",segmentText:s,paramName:null,pattern:new RegExp(`^${s}$`)})}}this._hasGuard=e.hasGuard||!1,this._hasGuard&&(this._guardFallbackPath=e.guardFallback||"/",this._waitForSetGuardHandler=new Promise(t=>{this._resolveSetGuardHandler=t}))}setParams(t,e){this._params=t,this._typedParams=e,this._active=!0,this._target.dispatchEvent(new CustomEvent("wcs-route:params-changed",{detail:{params:t,typedParams:e},bubbles:!0}))}clearParams(){this._params={},this._typedParams={},this._active=!1}shouldChange(t){for(const e of this.paramNames)if(this._params[e]!==t[e])return!0;return!1}get guardHandler(){return this._guardHandler||o(`${n.tagNames.route} has no guardHandler.`),this._guardHandler}set guardHandler(t){this._resolveSetGuardHandler?.(),this._guardHandler=t}async guardCheck(t){if(this._hasGuard&&this._waitForSetGuardHandler&&await this._waitForSetGuardHandler,this._guardHandler){const e=t.path,a=t.lastPath;if(!await this._guardHandler(e,a))throw new l("Navigation cancelled by guard.",this._guardFallbackPath)}}}class d extends HTMLElement{static wcBindable=c.wcBindable;_core;_routeParentNode=null;_routeChildNodes=[];_routerNode=null;_uuid=r();_placeHolder=document.createComment(`@@route:${this._uuid}`);_childNodeArray;_childIndex=0;_initialized=!1;constructor(){super(),this._core=new c(this)}get routeParentNode(){return this._routeParentNode}get routeChildNodes(){return this._routeChildNodes}get routerNode(){return this._routerNode||o(`${n.tagNames.route} has no routerNode.`),this._routerNode}get uuid(){return this._uuid}get placeHolder(){return this._placeHolder}get childNodeArray(){return void 0===this._childNodeArray&&(this._childNodeArray=Array.from(this.childNodes)),this._childNodeArray}get routes(){return this.routeParentNode?this.routeParentNode.routes.concat(this):[this]}get childIndex(){return this._childIndex}get path(){return this._core.path}get name(){return this._core.name}get isRelative(){return this._core.isRelative}get absolutePath(){return this._core.absolutePath}get segmentInfos(){return this._core.segmentInfos}get absoluteSegmentInfos(){return this._core.absoluteSegmentInfos}get params(){return this._core.params}get typedParams(){return this._core.typedParams}get paramNames(){return this._core.paramNames}get absoluteParamNames(){return this._core.absoluteParamNames}get weight(){return this._core.weight}get absoluteWeight(){return this._core.absoluteWeight}get segmentCount(){return this._core.segmentCount}get absoluteSegmentCount(){return this._core.absoluteSegmentCount}get fullpath(){return this.absolutePath}get guardHandler(){return this._core.guardHandler}set guardHandler(t){this._core.guardHandler=t}setParams(t,e){this._core.setParams(t,e)}clearParams(){this._core.clearParams()}shouldChange(t){return this._core.shouldChange(t)}async guardCheck(t){return this._core.guardCheck(t)}testAncestorNode(t){let e=this._routeParentNode;for(;e;){if(e===t)return!0;e=e.routeParentNode}return!1}initialize(t,e){if(this._initialized)return;let a;this._initialized=!0;let s=!1,i=!1;this.hasAttribute("path")?a=this.getAttribute("path")||"":this.hasAttribute("index")?(a="",s=!0):this.hasAttribute("fallback")?(a="",i=!0):o(`${n.tagNames.route} should have a "path" or "index" attribute.`),this._routerNode=t,this._routeParentNode=e;const r=e||t;r.routeChildNodes.push(this),this._childIndex=r.routeChildNodes.length-1,i&&(e&&o(`${n.tagNames.route} with fallback attribute must be a direct child of ${n.tagNames.router}.`),t.fallbackRoute&&o(`${n.tagNames.router} can have only one fallback route.`),t.fallbackRoute=this),e&&(this._core.parentCore=e._core),this._core.parsePath(a,{isIndex:s,isFallback:i,hasGuard:this.hasAttribute("guard"),guardFallback:this.getAttribute("guard"),name:this.getAttribute("name")||""}),this.setAttribute("fullpath",this.absolutePath)}}const m=new Map;class p extends HTMLElement{_uuid=r();_initialized=!1;constructor(){super()}async _loadTemplateFromSource(t){try{const e=await fetch(t);e.ok||o(`${n.tagNames.layout} failed to fetch layout from source: ${t}, status: ${e.status}`);const a=await e.text();return m.set(t,a),a}catch(e){o(`${n.tagNames.layout} failed to load layout from source: ${t}, error: ${e}`)}}_loadTemplateFromDocument(t){const e=document.getElementById(`${t}`);return e&&e instanceof HTMLTemplateElement?e.innerHTML:null}async loadTemplate(){const t=this.getAttribute("src"),e=this.getAttribute("layout");t&&e&&console.warn(`${n.tagNames.layout} have both "src" and "layout" attributes.`);const a=document.createElement("template");if(t)m.has(t)?a.innerHTML=m.get(t)||"":(a.innerHTML=await this._loadTemplateFromSource(t)||"",m.set(t,a.innerHTML));else if(e){const t=this._loadTemplateFromDocument(e);t?a.innerHTML=t:console.warn(`${n.tagNames.layout} could not find template with id "${e}".`)}return a}get uuid(){return this._uuid}get enableShadowRoot(){return!!this.hasAttribute("enable-shadow-root")||!this.hasAttribute("disable-shadow-root")&&n.enableShadowRoot}get name(){return this.getAttribute("name")||""}_initialize(){this._initialized=!0}connectedCallback(){this._initialized||this._initialize()}}class g extends HTMLElement{_routesNode=null;_lastRoutes=[];_initialized=!1;constructor(){super()}get routesNode(){return this._routesNode||o(`${n.tagNames.outlet} has no routesNode.`),this._routesNode}set routesNode(t){this._routesNode=t}get rootNode(){return this.shadowRoot?this.shadowRoot:this}get lastRoutes(){return this._lastRoutes}set lastRoutes(t){this._lastRoutes=[...t]}_initialize(){n.enableShadowRoot&&this.attachShadow({mode:"open"}),this._initialized=!0}connectedCallback(){this._initialized||this._initialize()}}const _=new Set(["props","states","attr",""]);function f(t,e,a){for(const[s,n]of Object.entries(e))switch(a){case"props":t.props={...t.props,[s]:n};break;case"states":t.states={...t.states,[s]:n};break;case"attr":t.setAttribute(s,n);break;case"":t[s]=n}}function b(t,e){t.hasAttribute("data-bind")||o(`${t.tagName} has no 'data-bind' attribute.`);const a=t.getAttribute("data-bind")||"";_.has(a)||o(`${t.tagName} has invalid 'data-bind' attribute: ${a}`);const s=a,n=function(t){const e=t.tagName.toLowerCase();if(e.includes("-"))return e;const a=t.getAttribute("is");return a&&a.includes("-")?a:null}(t);n&&void 0===customElements.get(n)?customElements.whenDefined(n).then(()=>{t.isConnected&&f(t,e,s)}).catch(()=>{o(`Failed to define custom element: ${n}`)}):f(t,e,s)}class y extends HTMLElement{_layout=null;_initialized=!1;_layoutChildNodes=[];constructor(){super()}get layout(){return this._layout||o(`${n.tagNames.layoutOutlet} has no layout.`),this._layout}set layout(t){this._layout=t,this.setAttribute("name",t.name)}get name(){return this.layout.name}async _initialize(){this._initialized=!0,this.layout.enableShadowRoot&&this.attachShadow({mode:"open"});const t=await this.layout.loadTemplate();if(this.shadowRoot){this.shadowRoot.appendChild(t.content.cloneNode(!0));for(const t of Array.from(this.layout.childNodes))this._layoutChildNodes.push(t),this.appendChild(t)}else{const e=t.content.cloneNode(!0),a=new Map;e.querySelectorAll("slot").forEach(t=>{const e=t.getAttribute("name")||"";a.has(e)?console.warn(`${n.tagNames.layoutOutlet} duplicate slot name "${e}" in layout template.`):a.set(e,t)});const s=new Map,i=document.createDocumentFragment();for(const t of Array.from(this.layout.childNodes)){if(this._layoutChildNodes.push(t),t instanceof Element){const e=t.getAttribute("slot")||"";if(e.length>0&&a.has(e)){s.has(e)||s.set(e,document.createDocumentFragment()),s.get(e)?.appendChild(t);continue}}i.appendChild(t)}for(const[t,e]of a){const a=s.get(t);a&&e.replaceWith(a)}const r=a.get("");r&&r.replaceWith(i),this.appendChild(e)}}async connectedCallback(){this._initialized||await this._initialize()}assignParams(t){for(const e of this._layoutChildNodes)e instanceof Element&&(e.querySelectorAll("[data-bind]").forEach(e=>{b(e,t)}),e.hasAttribute("data-bind")&&b(e,t))}}function N(){return document.createElement(n.tagNames.layoutOutlet)}function w(t,e){(async function(t){let e=null;const a=t.text+"\n//# sourceURL=wcs-guard-handler\n";if("function"==typeof URL.createObjectURL){const t=new Blob([a],{type:"application/javascript"}),s=URL.createObjectURL(t);try{e=await import(s)}catch{}finally{URL.revokeObjectURL(s)}}if(!e){const t=btoa(String.fromCodePoint(...(new TextEncoder).encode(a)));e=await import(`data:application/javascript;base64,${t}`)}return e&&"function"==typeof e.default?e.default:null})(t).then(t=>{t&&(e.guardHandler=t)})}function v(t,e){let a=t.get(e.absolutePath);a||(a=[]);for(const t of a)if(!e.testAncestorNode(t)){console.warn(`Duplicate route path detected: '${e.absolutePath}' (defined as '${e.path}')`);break}a.push(e),1===a.length&&t.set(e.absolutePath,a)}async function C(t,e,a,s,i){const r=a.length>0?a[a.length-1]:null,o=document.createDocumentFragment(),l=Array.from(e.childNodes);for(const e of l)if(e.nodeType===Node.ELEMENT_NODE){let l=e,h=e;const u=h.tagName.toLowerCase();if(u===n.tagNames.route){const e=document.createDocumentFragment();for(const t of Array.from(h.childNodes))e.appendChild(t);const n=document.importNode(h,!0);customElements.upgrade(n),n.appendChild(e);const o=n;o.initialize(t,r),v(i,o),a.push(o),s.set(o.uuid,o),l=o.placeHolder,h=o}else{if(u===n.tagNames.guardHandler){if(a.length>0){const t=a[a.length-1],e=h.querySelector('script[type="module"]');e&&w(e,t)}continue}if(u===n.tagNames.layout){const t=document.createDocumentFragment();for(const e of Array.from(h.childNodes))t.appendChild(e);const e=document.importNode(h,!0);customElements.upgrade(e),e.appendChild(t);const a=e,s=N();s.layout=a,l=s,h=e}}const c=await C(t,h,a,s,i);h.innerHTML="",h.appendChild(c),o.appendChild(l)}else o.appendChild(e);return o}async function E(t){const e=new Map,a=new Map;return await C(t,t.template.content,[],e,a)}function P(t,e,a,s,n,i){const r=a.concat(e),o=function(t,e,a){const s={},n={};let i=!0,r=!1,o=0,l=0;for(;o<t.absoluteSegmentInfos.length;){const e=t.absoluteSegmentInfos[o];if(e.isIndex){o++;continue}if(0===o&&""===e.segmentText&&"static"===e.type){o++;continue}const u=a[l];if(void 0===u){i=!1;break}let c=!1;if("param"===e.type){const t=e.paramType||"any",a=h[t].parse(u);void 0!==a&&(e.paramName&&(s[e.paramName]=u,n[e.paramName]=a),c=!0)}else c=null!==e.pattern.exec(u);if(!c){i=!1;break}if("catch-all"===e.type){const t=a.slice(l).join("/");s["*"]=t,n["*"]=t,r=!0;break}o++,l++}let u=!1;return i&&(r||o===t.absoluteSegmentInfos.length&&l===a.length||o===t.absoluteSegmentInfos.length&&l===a.length-1&&""===a.at(-1))&&(u=!0),u?{path:e,routes:t.routes,params:s,typedParams:n,lastPath:""}:null}(e,s,n);o&&i.push(o);for(const a of e.routeChildNodes)P(t,a,r,s,n,i)}function k(t){t.clearParams();for(const e of t.childNodeArray)e.parentNode?.removeChild(e)}function A(t,e){const a={},s={};for(const n of t.paramNames)a[n]=e.params[n],s[n]=e.typedParams[n];t.setParams(a,s);const i=t.placeHolder.parentNode,r=t.placeHolder.nextSibling;for(const e of t.childNodeArray){if(e.nodeType===Node.ELEMENT_NODE){const a=e;a.querySelectorAll("[data-bind]").forEach(e=>{b(e,t.typedParams)}),a.hasAttribute("data-bind")&&b(a,t.typedParams),a.querySelectorAll(n.tagNames.layoutOutlet).forEach(e=>{e.assignParams(t.typedParams)}),a.tagName.toLowerCase()===n.tagNames.layoutOutlet&&a.assignParams(t.typedParams)}r?i?.insertBefore(e,r):i?.appendChild(e)}return!0}async function x(t,e,a,s){const i=t.basename;let r=a;""!==i&&(a===i?r="":a.startsWith(i+"/")&&(r=a.slice(i.length)));const l=""===r?"/":r;let h=function(t,e){const a=[],s=t.routeChildNodes,n=[],i=e.split("/"),r=i.filter((t,e)=>!(0===e&&""===t||e===i.length-1&&""===t&&i.length>1));for(const i of s)P(t,i,a,e,r,n);return n.sort((t,e)=>{const a=t.routes.at(-1),s=e.routes.at(-1),n=a.absoluteSegmentCount-s.absoluteSegmentCount;if(0!==n)return-n;const i=a.absoluteWeight-s.absoluteWeight;return 0!==i?-i:a.childIndex-s.childIndex}),n.length>0?n[0]:null}(t,l);h||(t.fallbackRoute?h={routes:[t.fallbackRoute],params:{},typedParams:{},path:l,lastPath:s}:o(`${n.tagNames.router} No route matched for path: ${l}`)),h.lastPath=s;const u=e.lastRoutes;await async function(t,e,a){const s=new Set(e.routes);for(const t of a)s.has(t)||k(t);try{for(const t of e.routes)await t.guardCheck(e)}catch(e){const a=e;if("fallbackPath"in a){const e=a;return console.warn(`Navigation cancelled: ${a.message}. Redirecting to ${e.fallbackPath}`),void queueMicrotask(()=>{t.navigate(e.fallbackPath)})}throw e}const n=new Set(a);let i=!1;for(const t of e.routes)(!n.has(t)||t.shouldChange(e.params)||i)&&(i=A(t,e))}(t,h,u),t.path=l,e.lastRoutes=h.routes}function S(){const t=window.navigation;return t?"function"!=typeof t.addEventListener||"function"!=typeof t.removeEventListener?null:t:null}class $ extends HTMLElement{static wcBindable={protocol:"wc-bindable",version:1,properties:[{name:"navigateUrl",event:"wcs-router:navigate-url-changed"},{name:"path",event:"wcs-router:path-changed"}]};_outlet=null;_template=null;_routeChildNodes=[];_basename="";_path="";_initialized=!1;_fallbackRoute=null;_listeningPopState=!1;_navigateUrl=null;constructor(){super()}_normalizePathname(t){let e=t||"/";e.startsWith("/")||(e="/"+e),e=e.replace(/\/{2,}/g,"/");const a=n.basenameFileExtensions;if(a.length>0){const t=new RegExp(`\\/[^/]+(?:${a.map(t=>t.replace(/\./g,"\\.")).join("|")})$`,"i");e=e.replace(t,"")}return""===e&&(e="/"),e.length>1&&e.endsWith("/")&&(e=e.slice(0,-1)),e}_normalizeBasename(t){let e=t||"";if(!e)return"";e.startsWith("/")||(e="/"+e),e=e.replace(/\/{2,}/g,"/");const a=n.basenameFileExtensions;if(a.length>0){const t=new RegExp(`\\/[^/]+(?:${a.map(t=>t.replace(/\./g,"\\.")).join("|")})$`,"i");e=e.replace(t,"")}return e.length>1&&e.endsWith("/")&&(e=e.slice(0,-1)),"/"===e?"":e}_joinInternalPath(t,e){const a=this._normalizeBasename(t);let s=e.startsWith("/")?e:"/"+e;return s=this._normalizePathname(s),a?"/"===s?a+"/":a+s:s}_notifyLocationChange(){window.dispatchEvent(new CustomEvent("wcs:navigate"))}_getBasename(){let t=new URL(document.baseURI).pathname||"/";return"/"===t?"":this._normalizeBasename(t)}get basename(){return this._basename}_getOutlet(){const t=this.nextElementSibling;if(t&&t.matches(n.tagNames.outlet))return t;const e=document.createElement(n.tagNames.outlet);return this.parentNode?this.parentNode.insertBefore(e,this.nextSibling):document.body.appendChild(e),e}_getTemplate(){return this.querySelector("template")}get outlet(){return this._outlet||o(`${n.tagNames.router} has no outlet.`),this._outlet}get template(){return this._template||o(`${n.tagNames.router} has no template.`),this._template}get routeChildNodes(){return this._routeChildNodes}get path(){return this._path}set path(t){const e=this._path!==t;this._path=t,e&&this.dispatchEvent(new CustomEvent("wcs-router:path-changed",{detail:t,bubbles:!0}))}get fallbackRoute(){return this._fallbackRoute}set fallbackRoute(t){this._fallbackRoute=t}get navigateUrl(){return this._navigateUrl}set navigateUrl(t){null!=t&&""!==t&&(this._navigateUrl=t,this.navigate(t).then(()=>{this._navigateUrl=null,this.dispatchEvent(new CustomEvent("wcs-router:navigate-url-changed",{detail:null,bubbles:!0}))}))}async navigate(t){const e=this._joinInternalPath(this._basename,t),a=S();a?.navigate?a.navigate(e):(history.pushState(null,"",e),await x(this,this.outlet,e,this._path),this._notifyLocationChange())}_isOwnPath(t){return""===this._basename||(t===this._basename||t.startsWith(this._basename+"/"))}_onNavigateFunc(t){if(!t.canIntercept||t.hashChange||null!==t.downloadRequest)return;const e=new URL(t.destination.url),a=this._normalizePathname(e.pathname);if(!this._isOwnPath(a))return;const s=this;t.intercept({handler:async()=>{await x(s,s.outlet,a,s.path)}})}_onNavigate=this._onNavigateFunc.bind(this);_onPopState=async()=>{const t=this._normalizePathname(window.location.pathname);this._isOwnPath(t)&&(await x(this,this.outlet,t,this._path),this._notifyLocationChange())};async _initialize(){this._initialized=!0,this._basename=this._normalizeBasename(this.getAttribute("basename")||this._getBasename()||"");const t=null!==document.querySelector("base[href]"),e=new URL(window.location.href);""!==this._basename||t||"/"===e.pathname||o(`${n.tagNames.router} basename is empty, but current path is not "/".`),this._outlet=this._getOutlet(),this._outlet.routesNode=this,this._template=this._getTemplate(),this._template||o(`${n.tagNames.router} should have a <template> child element.`);const a=await E(this);this._outlet.rootNode.appendChild(a),0===this.routeChildNodes.length&&o(`${n.tagNames.router} has no route definitions.`);const s=this._normalizePathname(window.location.pathname);await x(this,this.outlet,s,this._path),this._notifyLocationChange()}async connectedCallback(){this._initialized||await this._initialize(),S()?.addEventListener("navigate",this._onNavigate),S()?.addEventListener||this._listeningPopState||(window.addEventListener("popstate",this._onPopState),this._listeningPopState=!0)}disconnectedCallback(){S()?.removeEventListener("navigate",this._onNavigate),this._listeningPopState&&(window.removeEventListener("popstate",this._onPopState),this._listeningPopState=!1)}}class R extends HTMLElement{static get observedAttributes(){return["to"]}_childNodeArray=[];_uuid=r();_path="";_router=null;_anchorElement=null;_initialized=!1;_onClick;constructor(){super()}get uuid(){return this._uuid}get router(){if(this._router)return this._router;const t=this.closest(n.tagNames.router);if(t)return this._router=t;const e=this.getRootNode(),a=e.querySelector?.(n.tagNames.router);if(a)return this._router=a;o(`${n.tagNames.link} is not connected to a router.`)}_initialize(){this.style.display="none",this._childNodeArray=Array.from(this.childNodes),this._path=this.getAttribute("to")||"",this._initialized=!0}_normalizePathname(t){let e=t||"/";return e.startsWith("/")||(e="/"+e),e=e.replace(/\/{2,}/g,"/"),e.length>1&&e.endsWith("/")&&(e=e.slice(0,-1)),e}_joinInternalPath(t,e){const a=(t||"").replace(/\/{2,}/g,"/").replace(/\/$/,""),s=e.startsWith("/")?e:"/"+e,n=this._normalizePathname(s);return a?"/"===n?a+"/":a+n:n}_setAnchorHref(t,e){if(e.startsWith("/"))t.href=this._joinInternalPath(this.router.basename,e);else try{t.href=new URL(e).toString()}catch{o(`[${n.tagNames.link}] Invalid URL in 'to' attribute: ${e}`)}}connectedCallback(){this._initialized||this._initialize();const t=this.parentNode;if(!t)return;const e=this.nextSibling,a=document.createElement("a");this._setAnchorHref(a,this._path);for(const t of this._childNodeArray)a.appendChild(t);e?t.insertBefore(a,e):t.appendChild(a),this._anchorElement=a,S()?.addEventListener("currententrychange",this._updateActiveState),window.addEventListener("wcs:navigate",this._updateActiveState),window.addEventListener("popstate",this._updateActiveState),this._path.startsWith("/")&&!S()?.navigate&&(this._onClick=async t=>{t.defaultPrevented||0===t.button&&(t.metaKey||t.ctrlKey||t.shiftKey||t.altKey||(t.preventDefault(),await this.router.navigate(this._path),this._updateActiveState()))},a.addEventListener("click",this._onClick)),this._updateActiveState()}disconnectedCallback(){S()?.removeEventListener("currententrychange",this._updateActiveState),window.removeEventListener("wcs:navigate",this._updateActiveState),window.removeEventListener("popstate",this._updateActiveState),this._anchorElement&&(this._onClick&&(this._anchorElement.removeEventListener("click",this._onClick),this._onClick=void 0),this._anchorElement.remove(),this._anchorElement=null);for(const t of this._childNodeArray)t.parentNode?.removeChild(t)}attributeChangedCallback(t,e,a){"to"===t&&e!==a&&(this._path=a||"",this._anchorElement&&(this._setAnchorHref(this._anchorElement,this._path),this._updateActiveState()))}_updateActiveState=()=>{const t=this._normalizePathname(new URL(window.location.href).pathname),e=this._normalizePathname(this._path.startsWith("/")?this._joinInternalPath(this.router.basename,this._path):this._path);this._anchorElement&&(t===e?this._anchorElement.classList.add("active"):this._anchorElement.classList.remove("active"))};get anchorElement(){return this._anchorElement}}const H=[],L=new Map;let z=!1;class I extends HTMLElement{_initialized=!1;_childElementArray=[];constructor(){super(),this.style.display="none"}_initialize(){if(!this._initialized){this._initialized=!0,this._childElementArray=Array.from(this.children);for(const t of this._childElementArray)this.removeChild(t)}}connectedCallback(){this._initialize(),z||(this._captureInitialHead(),z=!0),H.push(this),this._reapplyHead()}disconnectedCallback(){const t=H.indexOf(this);-1!==t&&H.splice(t,1),this._reapplyHead()}get childElementArray(){return this._initialized||o("Head component is not initialized yet."),this._childElementArray}_getKey(t){const e=t.tagName.toLowerCase();if("title"===e)return"title";if("meta"===e){return`meta:${t.getAttribute("name")||""}:${t.getAttribute("property")||""}:${t.getAttribute("http-equiv")||""}:${t.hasAttribute("charset")?"charset":""}:${t.getAttribute("media")||""}`}if("link"===e){return`link:${t.getAttribute("rel")||""}:${t.getAttribute("href")||""}:${t.getAttribute("media")||""}`}return"base"===e?"base":`${e}:${t.outerHTML.slice(0,100)}`}_findInHead(t){const e=document.head;for(const a of Array.from(e.children))if(this._getKey(a)===t)return a;return null}_captureInitialHead(){const t=document.head;for(const e of Array.from(t.children)){const t=this._getKey(e);L.has(t)||L.set(t,e.cloneNode(!0))}}_reapplyHead(){const t=new Set;for(const e of H)for(const a of e._childElementArray)t.add(this._getKey(a));for(const e of L.keys())t.add(e);for(const e of Array.from(document.head.children))t.add(this._getKey(e));for(const e of t){let t=null;for(let a=H.length-1;a>=0;a--){const s=H[a];for(const a of s._childElementArray)if(this._getKey(a)===e){t=a.cloneNode(!0);break}if(t)break}if(!t&&L.has(e)){t=L.get(e).cloneNode(!0)}const a=this._findInHead(e);t?a?a.replaceWith(t):document.head.appendChild(t):a?.remove()}}}function T(){customElements.get(n.tagNames.layout)||customElements.define(n.tagNames.layout,p),customElements.get(n.tagNames.layoutOutlet)||customElements.define(n.tagNames.layoutOutlet,y),customElements.get(n.tagNames.outlet)||customElements.define(n.tagNames.outlet,g),customElements.get(n.tagNames.route)||customElements.define(n.tagNames.route,d),customElements.get(n.tagNames.router)||customElements.define(n.tagNames.router,$),customElements.get(n.tagNames.link)||customElements.define(n.tagNames.link,R),customElements.get(n.tagNames.head)||customElements.define(n.tagNames.head,I)}function F(e){var a;e&&((a=e).tagNames&&Object.assign(t.tagNames,a.tagNames),"boolean"==typeof a.enableShadowRoot&&(t.enableShadowRoot=a.enableShadowRoot),Array.isArray(a.basenameFileExtensions)&&(t.basenameFileExtensions=a.basenameFileExtensions),s=null),T()}export{d as Route,c as RouteCore,$ as Router,F as bootstrapRouter,i as getConfig};
2
2
  //# sourceMappingURL=index.esm.min.js.map