Comparing version 4.4.4 to 4.5.0
@@ -1,2 +0,2 @@ | ||
import t from"delegate-it";import{match as e}from"path-to-regexp";function i(){return i=Object.assign?Object.assign.bind():function(t){for(var e=1;e<arguments.length;e++){var i=arguments[e];for(var s in i)Object.prototype.hasOwnProperty.call(i,s)&&(t[s]=i[s])}return t},i.apply(this,arguments)}const s=(t,e)=>String(t).toLowerCase().replace(/[\s/_.]+/g,"-").replace(/[^\w-]+/g,"").replace(/--+/g,"-").replace(/^-+|-+$/g,"")||e||"",n=({hash:t}={})=>location.pathname+location.search+(t?location.hash:""),o=(t,e={})=>{const s=i({url:t=t||n({hash:!0}),random:Math.random(),source:"swup"},e);history.pushState(s,"",t)},r=(t=null,e={})=>{t=t||n({hash:!0});const s=i({},history.state||{},{url:t,random:Math.random(),source:"swup"},e);history.replaceState(s,"",t)},a=(e,s,n,o)=>{const r=new AbortController;return o=i({},o,{signal:r.signal}),t(e,s,n,o),{destroy:()=>r.abort()}};class l extends URL{constructor(t,e=document.baseURI){super(t.toString(),e),Object.setPrototypeOf(this,l.prototype)}get url(){return this.pathname+this.search}static fromElement(t){const e=t.getAttribute("href")||t.getAttribute("xlink:href")||"";return new l(e)}static fromUrl(t){return new l(t)}}const h=(t,i)=>{try{return e(t,i)}catch(e){throw new Error(`[swup] Error parsing path "${String(t)}":\n${String(e)}`)}};class c extends Error{constructor(t,e){super(t),this.url=void 0,this.status=void 0,this.aborted=void 0,this.timedOut=void 0,this.name="FetchError",this.url=e.url,this.status=e.status,this.aborted=e.aborted||!1,this.timedOut=e.timedOut||!1}}async function u(t,e={}){var s;t=l.fromUrl(t).url;const n=i({},this.options.requestHeaders,e.headers),o=null!=(s=e.timeout)?s:this.options.timeout,r=new AbortController,{signal:a}=r;e=i({},e,{headers:n,signal:a});let h,u=!1,d=null;o&&o>0&&(d=setTimeout(()=>{u=!0,r.abort("timeout")},o));try{h=await this.hooks.call("fetch:request",{url:t,options:e},(t,{url:e,options:i})=>fetch(e,i)),d&&clearTimeout(d)}catch(e){if(u)throw this.hooks.call("fetch:timeout",{url:t}),new c(`Request timed out: ${t}`,{url:t,timedOut:u});if("AbortError"===(null==e?void 0:e.name)||a.aborted)throw new c(`Request aborted: ${t}`,{url:t,aborted:!0});throw e}const{status:p,url:m}=h,g=await h.text();if(500===p)throw this.hooks.call("fetch:error",{status:p,response:h,url:m}),new c(`Server error: ${m}`,{status:p,url:m});if(!g)throw new c(`Empty response: ${m}`,{status:p,url:m});const{url:f}=l.fromUrl(m),w={url:f,html:g};return!this.visit.cache.write||e.method&&"GET"!==e.method||t!==f||this.cache.set(w.url,w),w}class d{constructor(t){this.swup=void 0,this.pages=new Map,this.swup=t}get size(){return this.pages.size}get all(){const t=new Map;return this.pages.forEach((e,s)=>{t.set(s,i({},e))}),t}has(t){return this.pages.has(this.resolve(t))}get(t){const e=this.pages.get(this.resolve(t));return e?i({},e):e}set(t,e){e=i({},e,{url:t=this.resolve(t)}),this.pages.set(t,e),this.swup.hooks.callSync("cache:set",{page:e})}update(t,e){t=this.resolve(t);const s=i({},this.get(t),e,{url:t});this.pages.set(t,s)}delete(t){this.pages.delete(this.resolve(t))}clear(){this.pages.clear(),this.swup.hooks.callSync("cache:clear",void 0)}prune(t){this.pages.forEach((e,i)=>{t(i,e)&&this.delete(i)})}resolve(t){const{url:e}=l.fromUrl(t);return this.swup.resolveUrl(e)}}const p=(t,e=document)=>e.querySelector(t),m=(t,e=document)=>Array.from(e.querySelectorAll(t)),g=()=>new Promise(t=>{requestAnimationFrame(()=>{requestAnimationFrame(()=>{t()})})});function f(t){return!!t&&("object"==typeof t||"function"==typeof t)&&"function"==typeof t.then}function w(t,e=[]){return new Promise((i,s)=>{const n=t(...e);f(n)?n.then(i,s):i(n)})}function v(t){var e;return null==(e=t=t||document.body)?void 0:e.offsetHeight}const y=t=>window.CSS&&window.CSS.escape?CSS.escape(t):t,k=t=>1e3*Number(t.slice(0,-1).replace(",","."));class b{constructor(t){this.swup=void 0,this.swupClasses=["to-","is-changing","is-rendering","is-popstate","is-animating"],this.swup=t}get selectors(){const{scope:t}=this.swup.visit.animation;return"containers"===t?this.swup.visit.containers:"html"===t?["html"]:Array.isArray(t)?t:[]}get selector(){return this.selectors.join(",")}get targets(){return this.selector.trim()?m(this.selector):[]}add(...t){this.targets.forEach(e=>e.classList.add(...t))}remove(...t){this.targets.forEach(e=>e.classList.remove(...t))}clear(){this.targets.forEach(t=>{const e=t.className.split(" ").filter(t=>this.isSwupClass(t));t.classList.remove(...e)})}isSwupClass(t){return this.swupClasses.some(e=>t.startsWith(e))}}function S({to:t,from:e=this.currentPageUrl,hash:i,el:s,event:n}){return{id:Math.random(),from:{url:e},to:{url:t,hash:i},containers:this.options.containers,animation:{animate:!0,wait:!1,name:void 0,scope:this.options.animationScope,selector:this.options.animationSelector},trigger:{el:s,event:n},cache:{read:this.options.cache,write:this.options.cache},history:{action:"push",popstate:!1,direction:void 0},scroll:{reset:!0,target:void 0}}}class E{constructor(t){this.swup=void 0,this.registry=new Map,this.hooks=["animation:out:start","animation:out:await","animation:out:end","animation:in:start","animation:in:await","animation:in:end","animation:skip","cache:clear","cache:set","content:replace","content:scroll","enable","disable","fetch:request","fetch:error","fetch:timeout","history:popstate","link:click","link:self","link:anchor","link:newtab","page:load","page:view","scroll:top","scroll:anchor","visit:start","visit:transition","visit:end"],this.swup=t,this.init()}init(){this.hooks.forEach(t=>this.create(t))}create(t){this.registry.has(t)||this.registry.set(t,new Map)}exists(t){return this.registry.has(t)}get(t){const e=this.registry.get(t);if(e)return e;console.error(`Unknown hook '${t}'`)}clear(){this.registry.forEach(t=>t.clear())}on(t,e,s={}){const n=this.get(t);if(!n)return console.warn(`Hook '${t}' not found.`),()=>{};const o=i({},s,{id:n.size+1,hook:t,handler:e});return n.set(e,o),()=>this.off(t,e)}before(t,e,s={}){return this.on(t,e,i({},s,{before:!0}))}replace(t,e,s={}){return this.on(t,e,i({},s,{replace:!0}))}once(t,e,s={}){return this.on(t,e,i({},s,{once:!0}))}off(t,e){const i=this.get(t);i&&e?i.delete(e)||console.warn(`Handler for hook '${t}' not found.`):i&&i.clear()}async call(t,e,i){const{before:s,handler:n,after:o}=this.getHandlers(t,i);await this.run(s,e);const[r]=await this.run(n,e);return await this.run(o,e),this.dispatchDomEvent(t,e),r}callSync(t,e,i){const{before:s,handler:n,after:o}=this.getHandlers(t,i);this.runSync(s,e);const[r]=this.runSync(n,e);return this.runSync(o,e),this.dispatchDomEvent(t,e),r}async run(t,e){const i=[];for(const{hook:s,handler:n,defaultHandler:o,once:r}of t){const t=await w(n,[this.swup.visit,e,o]);i.push(t),r&&this.off(s,n)}return i}runSync(t,e){const i=[];for(const{hook:s,handler:n,defaultHandler:o,once:r}of t){const t=n(this.swup.visit,e,o);i.push(t),f(t)&&console.warn(`Promise returned from handler for synchronous hook '${s}'.Swup will not wait for it to resolve.`),r&&this.off(s,n)}return i}getHandlers(t,e){const i=this.get(t);if(!i)return{found:!1,before:[],handler:[],after:[],replaced:!1};const s=Array.from(i.values()),n=this.sortRegistrations,o=s.filter(({before:t,replace:e})=>t&&!e).sort(n),r=s.filter(({replace:t})=>t).filter(t=>!0).sort(n),a=s.filter(({before:t,replace:e})=>!t&&!e).sort(n),l=r.length>0;let h=[];if(e&&(h=[{id:0,hook:t,handler:e}],l)){const i=r.length-1,s=t=>{const i=r[t-1];return i?(e,n)=>i.handler(e,n,s(t-1)):e};h=[{id:0,hook:t,handler:r[i].handler,defaultHandler:s(i)}]}return{found:!0,before:o,handler:h,after:a,replaced:l}}sortRegistrations(t,e){var i,s;return(null!=(i=t.priority)?i:0)-(null!=(s=e.priority)?s:0)||t.id-e.id||0}dispatchDomEvent(t,e){const i={hook:t,args:e,visit:this.swup.visit};document.dispatchEvent(new CustomEvent("swup:any",{detail:i,bubbles:!0})),document.dispatchEvent(new CustomEvent(`swup:${t}`,{detail:i,bubbles:!0}))}}const P=t=>{if(t&&"#"===t.charAt(0)&&(t=t.substring(1)),!t)return null;const e=decodeURIComponent(t);let i=document.getElementById(t)||document.getElementById(e)||p(`a[name='${y(t)}']`)||p(`a[name='${y(e)}']`);return i||"top"!==t||(i=document.body),i},U="transition",C="animation";async function $({elements:t,selector:e}){if(!1===e&&!t)return;let i=[];if(t)i=Array.from(t);else if(e&&(i=m(e,document.body),!i.length))return void console.warn(`[swup] No elements found matching animationSelector \`${e}\``);const s=i.map(t=>function(t){const{type:e,timeout:i,propCount:s}=function(t,e){const i=window.getComputedStyle(t),s=x(i,`${U}Delay`),n=x(i,`${U}Duration`),o=H(s,n),r=x(i,`${C}Delay`),a=x(i,`${C}Duration`),l=H(r,a);let h=null,c=0,u=0;return c=Math.max(o,l),h=c>0?o>l?U:C:null,u=h?h===U?n.length:a.length:0,{type:h,timeout:c,propCount:u}}(t);return!(!e||!i)&&new Promise(n=>{const o=`${e}end`,r=performance.now();let a=0;const l=()=>{t.removeEventListener(o,h),n()},h=e=>{if(e.target===t){if(!function(t){return[`${U}end`,`${C}end`].includes(t.type)}(e))throw new Error("Not a transition or animation event.");(performance.now()-r)/1e3<e.elapsedTime||++a>=s&&l()}};setTimeout(()=>{a<s&&l()},i+1),t.addEventListener(o,h)})}(t));s.filter(Boolean).length>0?await Promise.all(s):e&&console.warn(`[swup] No CSS animation duration defined on elements matching \`${e}\``)}function x(t,e){return(t[e]||"").split(", ")}function H(t,e){for(;t.length<e.length;)t=t.concat(t);return Math.max(...e.map((e,i)=>k(e)+k(t[i])))}function A(t,e={},s={}){if("string"!=typeof t)throw new Error("swup.navigate() requires a URL parameter");if(this.shouldIgnoreVisit(t,{el:s.el,event:s.event}))return void(window.location.href=t);const{url:n,hash:o}=l.fromUrl(t);this.visit=this.createVisit(i({},s,{to:n,hash:o})),this.performNavigation(e)}async function q(t={}){this.navigating=!0;const e=this.visit,{el:i}=e.trigger;t.referrer=t.referrer||this.currentPageUrl,!1===t.animate&&(e.animation.animate=!1),e.animation.animate||this.classes.clear();const s=t.history||(null==i?void 0:i.getAttribute("data-swup-history"))||void 0;s&&["push","replace"].includes(s)&&(e.history.action=s);const a=t.animation||(null==i?void 0:i.getAttribute("data-swup-animation"))||void 0;var l,h;a&&(e.animation.name=a),"object"==typeof t.cache?(e.cache.read=null!=(l=t.cache.read)?l:e.cache.read,e.cache.write=null!=(h=t.cache.write)?h:e.cache.write):void 0!==t.cache&&(e.cache={read:!!t.cache,write:!!t.cache}),delete t.cache;try{await this.hooks.call("visit:start",void 0);const i=this.hooks.call("page:load",{options:t},async(t,e)=>{let i;return t.cache.read&&(i=this.cache.get(t.to.url)),e.page=i||await this.fetchPage(t.to.url,e.options),e.cache=!!i,e.page});if(!e.history.popstate){const t=e.to.url+e.to.hash;"replace"===e.history.action||e.to.url===this.currentPageUrl?r(t):(this.currentHistoryIndex++,o(t,{index:this.currentHistoryIndex}))}if(this.currentPageUrl=n(),e.animation.wait){const{html:t}=await i;e.to.html=t}await this.hooks.call("visit:transition",void 0,async t=>{const e=this.animatePageOut(),[s]=await Promise.all([i,e]);return t.id===this.visit.id&&(await this.renderPage(s),await this.animatePageIn(),!0)}),await this.hooks.call("visit:end",void 0,()=>this.classes.clear()),this.navigating=!1}catch(t){if(!t||null!=t&&t.aborted)return;console.error(t),this.options.skipPopStateHandling=()=>(window.location.href=e.to.url+e.to.hash,!0),window.history.go(-1)}}const I=async function(){this.visit.animation.animate?(await this.hooks.call("animation:out:start",void 0,t=>{this.classes.add("is-changing","is-leaving","is-animating"),t.history.popstate&&this.classes.add("is-popstate"),t.animation.name&&this.classes.add(`to-${s(t.animation.name)}`)}),await this.hooks.call("animation:out:await",{skip:!1},async(t,{skip:e})=>{e||await this.awaitAnimations({selector:t.animation.selector})}),await this.hooks.call("animation:out:end",void 0)):await this.hooks.call("animation:skip",void 0)},R=function({html:t},{containers:e}=this.options){var i;const s=(new DOMParser).parseFromString(t,"text/html"),n=(null==(i=s.querySelector("title"))?void 0:i.innerText)||"";document.title=n;const o=m('[data-swup-persist]:not([data-swup-persist=""])'),r=e.map(t=>{const e=document.querySelector(t),i=s.querySelector(t);return e&&i?(e.replaceWith(i),!0):(e||console.warn(`[swup] Container missing in current document: ${t}`),i||console.warn(`[swup] Container missing in incoming document: ${t}`),!1)}).filter(Boolean);return o.forEach(t=>{const e=t.getAttribute("data-swup-persist"),i=p(`[data-swup-persist="${e}"]`);i&&i!==t&&i.replaceWith(t)}),r.length===e.length},L=function(){const t={behavior:"auto"},{target:e,reset:s}=this.visit.scroll,n=null!=e?e:this.visit.to.hash;let o=!1;return n&&(o=this.hooks.callSync("scroll:anchor",{hash:n,options:t},(t,{hash:e,options:i})=>{const s=this.getAnchorElement(e);return s&&s.scrollIntoView(i),!!s})),s&&!o&&(o=this.hooks.callSync("scroll:top",{options:t},(t,{options:e})=>(window.scrollTo(i({top:0,left:0},e)),!0))),o},O=async function(){if(!this.visit.animation.animate)return;const t=this.hooks.call("animation:in:await",{skip:!1},async(t,{skip:e})=>{e||await this.awaitAnimations({selector:t.animation.selector})});await g(),await this.hooks.call("animation:in:start",void 0,()=>{this.classes.remove("is-animating")}),await t,await this.hooks.call("animation:in:end",void 0)},N=async function(t){const{url:e,html:i}=t;this.classes.remove("is-leaving"),this.isSameResolvedUrl(n(),e)||(r(e),this.currentPageUrl=n(),this.visit.to.url=this.currentPageUrl),this.visit.animation.animate&&this.classes.add("is-rendering"),this.visit.to.html=i,await this.hooks.call("content:replace",{page:t},(t,{page:e})=>{if(!this.replaceContent(e,{containers:t.containers}))throw new Error("[swup] Container mismatch, aborting");t.animation.animate&&(this.classes.add("is-animating","is-changing","is-rendering"),t.animation.name&&this.classes.add(`to-${s(t.animation.name)}`))}),await this.hooks.call("content:scroll",void 0,()=>this.scrollToContent()),await this.hooks.call("page:view",{url:this.currentPageUrl,title:document.title})},T=function(t){var e;if(e=t,Boolean(null==e?void 0:e.isSwupPlugin)){if(t.swup=this,!t._checkRequirements||t._checkRequirements())return t._beforeMount&&t._beforeMount(),t.mount(),this.plugins.push(t),this.plugins}else console.error("Not a swup plugin instance",t)};function D(t){const e=this.findPlugin(t);if(e)return e.unmount(),e._afterUnmount&&e._afterUnmount(),this.plugins=this.plugins.filter(t=>t!==e),this.plugins;console.error("No such plugin",e)}function M(t){return this.plugins.find(e=>e===t||e.name===t||e.name===`Swup${String(t)}`)}function V(t){if("function"!=typeof this.options.resolveUrl)return console.warn("[swup] options.resolveUrl expects a callback function."),t;const e=this.options.resolveUrl(t);return e&&"string"==typeof e?e.startsWith("//")||e.startsWith("http")?(console.warn("[swup] options.resolveUrl needs to return a relative url"),t):e:(console.warn("[swup] options.resolveUrl needs to return a url"),t)}function W(t,e){return this.resolveUrl(t)===this.resolveUrl(e)}const B={animateHistoryBrowsing:!1,animationSelector:'[class*="transition-"]',animationScope:"html",cache:!0,containers:["#swup"],ignoreVisit:(t,{el:e}={})=>!(null==e||!e.closest("[data-no-swup]")),linkSelector:"a[href]",linkToSelf:"scroll",plugins:[],resolveUrl:t=>t,requestHeaders:{"X-Requested-With":"swup",Accept:"text/html, application/xhtml+xml"},skipPopStateHandling:t=>{var e;return"swup"!==(null==(e=t.state)?void 0:e.source)},timeout:0};class _{constructor(t={}){var e,s;this.version="4.4.4",this.options=void 0,this.defaults=B,this.plugins=[],this.visit=void 0,this.cache=void 0,this.hooks=void 0,this.classes=void 0,this.currentPageUrl=n(),this.currentHistoryIndex=void 0,this.clickDelegate=void 0,this.navigating=!1,this.use=T,this.unuse=D,this.findPlugin=M,this.log=()=>{},this.navigate=A,this.performNavigation=q,this.createVisit=S,this.delegateEvent=a,this.fetchPage=u,this.awaitAnimations=$,this.renderPage=N,this.replaceContent=R,this.animatePageIn=O,this.animatePageOut=I,this.scrollToContent=L,this.getAnchorElement=P,this.getCurrentUrl=n,this.resolveUrl=V,this.isSameResolvedUrl=W,this.options=i({},this.defaults,t),this.handleLinkClick=this.handleLinkClick.bind(this),this.handlePopState=this.handlePopState.bind(this),this.cache=new d(this),this.classes=new b(this),this.hooks=new E(this),this.visit=this.createVisit({to:""}),this.currentHistoryIndex=null!=(e=null==(s=history.state)?void 0:s.index)?e:1,this.checkRequirements()&&this.enable()}checkRequirements(){return"undefined"!=typeof Promise||(console.warn("Promise is not supported"),!1)}async enable(){var t;const{linkSelector:e}=this.options;this.clickDelegate=this.delegateEvent(e,"click",this.handleLinkClick),window.addEventListener("popstate",this.handlePopState),this.options.animateHistoryBrowsing&&(window.history.scrollRestoration="manual"),this.options.plugins.forEach(t=>this.use(t)),"swup"!==(null==(t=history.state)?void 0:t.source)&&r(null,{index:this.currentHistoryIndex}),await g(),await this.hooks.call("enable",void 0,()=>{document.documentElement.classList.add("swup-enabled")})}async destroy(){this.clickDelegate.destroy(),window.removeEventListener("popstate",this.handlePopState),this.cache.clear(),this.options.plugins.forEach(t=>this.unuse(t)),await this.hooks.call("disable",void 0,()=>{document.documentElement.classList.remove("swup-enabled")}),this.hooks.clear()}shouldIgnoreVisit(t,{el:e,event:i}={}){const{origin:s,url:n,hash:o}=l.fromUrl(t);return s!==window.location.origin||!(!e||!this.triggerWillOpenNewWindow(e))||!!this.options.ignoreVisit(n+o,{el:e,event:i})}handleLinkClick(t){const e=t.delegateTarget,{href:i,url:s,hash:n}=l.fromElement(e);this.shouldIgnoreVisit(i,{el:e,event:t})||(this.navigating&&s===this.visit.to.url?t.preventDefault():(this.visit=this.createVisit({to:s,hash:n,el:e,event:t}),t.metaKey||t.ctrlKey||t.shiftKey||t.altKey?this.hooks.call("link:newtab",{href:i}):0===t.button&&this.hooks.callSync("link:click",{el:e,event:t},()=>{var e;const i=null!=(e=this.visit.from.url)?e:"";t.preventDefault(),s&&s!==i?this.isSameResolvedUrl(s,i)||this.performNavigation():n?this.hooks.callSync("link:anchor",{hash:n},()=>{r(s+n),this.scrollToContent()}):this.hooks.callSync("link:self",void 0,()=>"navigate"===this.options.linkToSelf?this.performNavigation():(r(s),this.scrollToContent()))})))}handlePopState(t){var e,i,s,o;const r=null!=(e=null==(i=t.state)?void 0:i.url)?e:location.href;if(this.options.skipPopStateHandling(t))return;if(this.isSameResolvedUrl(n(),this.currentPageUrl))return;const{url:a,hash:h}=l.fromUrl(r);this.visit=this.createVisit({to:a,hash:h,event:t}),this.visit.history.popstate=!0;const c=null!=(s=null==(o=t.state)?void 0:o.index)?s:0;c&&c!==this.currentHistoryIndex&&(this.visit.history.direction=c-this.currentHistoryIndex>0?"forwards":"backwards",this.currentHistoryIndex=c),this.visit.animation.animate=!1,this.visit.scroll.reset=!1,this.visit.scroll.target=!1,this.options.animateHistoryBrowsing&&(this.visit.animation.animate=!0,this.visit.scroll.reset=!0),this.hooks.callSync("history:popstate",{event:t},()=>{this.performNavigation()})}triggerWillOpenNewWindow(t){return!!t.matches('[download], [target="_blank"]')}}export{l as Location,s as classify,o as createHistoryRecord,_ as default,a as delegateEvent,y as escapeCssIdentifier,v as forceReflow,n as getCurrentUrl,f as isPromise,h as matchPath,g as nextTick,p as query,m as queryAll,w as runAsPromise,k as toMs,r as updateHistoryRecord}; | ||
import t from"delegate-it";import{match as e}from"path-to-regexp";function i(){return i=Object.assign?Object.assign.bind():function(t){for(var e=1;e<arguments.length;e++){var i=arguments[e];for(var s in i)Object.prototype.hasOwnProperty.call(i,s)&&(t[s]=i[s])}return t},i.apply(this,arguments)}const s=(t,e)=>String(t).toLowerCase().replace(/[\s/_.]+/g,"-").replace(/[^\w-]+/g,"").replace(/--+/g,"-").replace(/^-+|-+$/g,"")||e||"",n=({hash:t}={})=>location.pathname+location.search+(t?location.hash:""),o=(t,e={})=>{const s=i({url:t=t||n({hash:!0}),random:Math.random(),source:"swup"},e);history.pushState(s,"",t)},r=(t=null,e={})=>{t=t||n({hash:!0});const s=i({},history.state||{},{url:t,random:Math.random(),source:"swup"},e);history.replaceState(s,"",t)},a=(e,s,n,o)=>{const r=new AbortController;return o=i({},o,{signal:r.signal}),t(e,s,n,o),{destroy:()=>r.abort()}};class l extends URL{constructor(t,e=document.baseURI){super(t.toString(),e),Object.setPrototypeOf(this,l.prototype)}get url(){return this.pathname+this.search}static fromElement(t){const e=t.getAttribute("href")||t.getAttribute("xlink:href")||"";return new l(e)}static fromUrl(t){return new l(t)}}const h=(t,i)=>{try{return e(t,i)}catch(e){throw new Error(`[swup] Error parsing path "${String(t)}":\n${String(e)}`)}};class c extends Error{constructor(t,e){super(t),this.url=void 0,this.status=void 0,this.aborted=void 0,this.timedOut=void 0,this.name="FetchError",this.url=e.url,this.status=e.status,this.aborted=e.aborted||!1,this.timedOut=e.timedOut||!1}}async function u(t,e={}){var s;t=l.fromUrl(t).url;const{visit:n=this.visit}=e,o=i({},this.options.requestHeaders,e.headers),r=null!=(s=e.timeout)?s:this.options.timeout,a=new AbortController,{signal:h}=a;e=i({},e,{headers:o,signal:h});let u,d=!1,p=null;r&&r>0&&(p=setTimeout(()=>{d=!0,a.abort("timeout")},r));try{u=await this.hooks.call("fetch:request",n,{url:t,options:e},(t,{url:e,options:i})=>fetch(e,i)),p&&clearTimeout(p)}catch(e){if(d)throw this.hooks.call("fetch:timeout",n,{url:t}),new c(`Request timed out: ${t}`,{url:t,timedOut:d});if("AbortError"===(null==e?void 0:e.name)||h.aborted)throw new c(`Request aborted: ${t}`,{url:t,aborted:!0});throw e}const{status:m,url:g}=u,f=await u.text();if(500===m)throw this.hooks.call("fetch:error",n,{status:m,response:u,url:g}),new c(`Server error: ${g}`,{status:m,url:g});if(!f)throw new c(`Empty response: ${g}`,{status:m,url:g});const{url:v}=l.fromUrl(g),w={url:v,html:f};return!n.cache.write||e.method&&"GET"!==e.method||t!==v||this.cache.set(w.url,w),w}class d{constructor(t){this.swup=void 0,this.pages=new Map,this.swup=t}get size(){return this.pages.size}get all(){const t=new Map;return this.pages.forEach((e,s)=>{t.set(s,i({},e))}),t}has(t){return this.pages.has(this.resolve(t))}get(t){const e=this.pages.get(this.resolve(t));return e?i({},e):e}set(t,e){e=i({},e,{url:t=this.resolve(t)}),this.pages.set(t,e),this.swup.hooks.callSync("cache:set",void 0,{page:e})}update(t,e){t=this.resolve(t);const s=i({},this.get(t),e,{url:t});this.pages.set(t,s)}delete(t){this.pages.delete(this.resolve(t))}clear(){this.pages.clear(),this.swup.hooks.callSync("cache:clear",void 0,void 0)}prune(t){this.pages.forEach((e,i)=>{t(i,e)&&this.delete(i)})}resolve(t){const{url:e}=l.fromUrl(t);return this.swup.resolveUrl(e)}}const p=(t,e=document)=>e.querySelector(t),m=(t,e=document)=>Array.from(e.querySelectorAll(t)),g=()=>new Promise(t=>{requestAnimationFrame(()=>{requestAnimationFrame(()=>{t()})})});function f(t){return!!t&&("object"==typeof t||"function"==typeof t)&&"function"==typeof t.then}function v(t,e=[]){return new Promise((i,s)=>{const n=t(...e);f(n)?n.then(i,s):i(n)})}function w(t){var e;return null==(e=t=t||document.body)?void 0:e.offsetHeight}const y=t=>window.CSS&&window.CSS.escape?CSS.escape(t):t,k=t=>1e3*Number(t.slice(0,-1).replace(",","."));class b{constructor(t){this.swup=void 0,this.swupClasses=["to-","is-changing","is-rendering","is-popstate","is-animating","is-leaving"],this.swup=t}get selectors(){const{scope:t}=this.swup.visit.animation;return"containers"===t?this.swup.visit.containers:"html"===t?["html"]:Array.isArray(t)?t:[]}get selector(){return this.selectors.join(",")}get targets(){return this.selector.trim()?m(this.selector):[]}add(...t){this.targets.forEach(e=>e.classList.add(...t))}remove(...t){this.targets.forEach(e=>e.classList.remove(...t))}clear(){this.targets.forEach(t=>{const e=t.className.split(" ").filter(t=>this.isSwupClass(t));t.classList.remove(...e)})}isSwupClass(t){return this.swupClasses.some(e=>t.startsWith(e))}}class S{constructor(t,e){this.id=void 0,this.state=void 0,this.from=void 0,this.to=void 0,this.containers=void 0,this.animation=void 0,this.trigger=void 0,this.cache=void 0,this.history=void 0,this.scroll=void 0;const{to:i,from:s=t.currentPageUrl,hash:n,el:o,event:r}=e;this.id=Math.random(),this.state=1,this.from={url:s},this.to={url:i,hash:n},this.containers=t.options.containers,this.animation={animate:!0,wait:!1,name:void 0,native:t.options.native,scope:t.options.animationScope,selector:t.options.animationSelector},this.trigger={el:o,event:r},this.cache={read:t.options.cache,write:t.options.cache},this.history={action:"push",popstate:!1,direction:void 0},this.scroll={reset:!0,target:void 0}}advance(t){this.state<t&&(this.state=t)}abort(){this.state=8}get done(){return this.state>=7}}function E(t){return new S(this,t)}class P{constructor(t){this.swup=void 0,this.registry=new Map,this.hooks=["animation:out:start","animation:out:await","animation:out:end","animation:in:start","animation:in:await","animation:in:end","animation:skip","cache:clear","cache:set","content:replace","content:scroll","enable","disable","fetch:request","fetch:error","fetch:timeout","history:popstate","link:click","link:self","link:anchor","link:newtab","page:load","page:view","scroll:top","scroll:anchor","visit:start","visit:transition","visit:abort","visit:end"],this.swup=t,this.init()}init(){this.hooks.forEach(t=>this.create(t))}create(t){this.registry.has(t)||this.registry.set(t,new Map)}exists(t){return this.registry.has(t)}get(t){const e=this.registry.get(t);if(e)return e;console.error(`Unknown hook '${t}'`)}clear(){this.registry.forEach(t=>t.clear())}on(t,e,s={}){const n=this.get(t);if(!n)return console.warn(`Hook '${t}' not found.`),()=>{};const o=i({},s,{id:n.size+1,hook:t,handler:e});return n.set(e,o),()=>this.off(t,e)}before(t,e,s={}){return this.on(t,e,i({},s,{before:!0}))}replace(t,e,s={}){return this.on(t,e,i({},s,{replace:!0}))}once(t,e,s={}){return this.on(t,e,i({},s,{once:!0}))}off(t,e){const i=this.get(t);i&&e?i.delete(e)||console.warn(`Handler for hook '${t}' not found.`):i&&i.clear()}async call(t,e,i,s){const[n,o,r]=this.parseCallArgs(t,e,i,s),{before:a,handler:l,after:h}=this.getHandlers(t,r);await this.run(a,n,o);const[c]=await this.run(l,n,o);return await this.run(h,n,o),this.dispatchDomEvent(t,n,o),c}callSync(t,e,i,s){const[n,o,r]=this.parseCallArgs(t,e,i,s),{before:a,handler:l,after:h}=this.getHandlers(t,r);this.runSync(a,n,o);const[c]=this.runSync(l,n,o);return this.runSync(h,n,o),this.dispatchDomEvent(t,n,o),c}parseCallArgs(t,e,i,s){return e instanceof S||"object"!=typeof e&&"function"!=typeof i?[e,i,s]:[void 0,e,i]}async run(t,e,i){const s=[];for(const{hook:n,handler:o,defaultHandler:r,once:a}of t){if(null!=e&&e.done)continue;a&&this.off(n,o);const t=await v(o,[e||this.swup.visit,i,r]);s.push(t)}return s}runSync(t,e,i){const s=[];for(const{hook:n,handler:o,defaultHandler:r,once:a}of t){if(null!=e&&e.done)continue;a&&this.off(n,o);const t=o(e||this.swup.visit,i,r);s.push(t),f(t)&&console.warn(`Promise returned from handler for synchronous hook '${n}'.Swup will not wait for it to resolve.`)}return s}getHandlers(t,e){const i=this.get(t);if(!i)return{found:!1,before:[],handler:[],after:[],replaced:!1};const s=Array.from(i.values()),n=this.sortRegistrations,o=s.filter(({before:t,replace:e})=>t&&!e).sort(n),r=s.filter(({replace:t})=>t).filter(t=>!0).sort(n),a=s.filter(({before:t,replace:e})=>!t&&!e).sort(n),l=r.length>0;let h=[];if(e&&(h=[{id:0,hook:t,handler:e}],l)){const i=r.length-1,s=t=>{const i=r[t-1];return i?(e,n)=>i.handler(e,n,s(t-1)):e};h=[{id:0,hook:t,handler:r[i].handler,defaultHandler:s(i)}]}return{found:!0,before:o,handler:h,after:a,replaced:l}}sortRegistrations(t,e){var i,s;return(null!=(i=t.priority)?i:0)-(null!=(s=e.priority)?s:0)||t.id-e.id||0}dispatchDomEvent(t,e,i){if(null!=e&&e.done)return;const s={hook:t,args:i,visit:e||this.swup.visit};document.dispatchEvent(new CustomEvent("swup:any",{detail:s,bubbles:!0})),document.dispatchEvent(new CustomEvent(`swup:${t}`,{detail:s,bubbles:!0}))}}const U=t=>{if(t&&"#"===t.charAt(0)&&(t=t.substring(1)),!t)return null;const e=decodeURIComponent(t);let i=document.getElementById(t)||document.getElementById(e)||p(`a[name='${y(t)}']`)||p(`a[name='${y(e)}']`);return i||"top"!==t||(i=document.body),i},C="transition",$="animation";async function x({elements:t,selector:e}){if(!1===e&&!t)return;let i=[];if(t)i=Array.from(t);else if(e&&(i=m(e,document.body),!i.length))return void console.warn(`[swup] No elements found matching animationSelector \`${e}\``);const s=i.map(t=>function(t){const{type:e,timeout:i,propCount:s}=function(t,e){const i=window.getComputedStyle(t),s=A(i,`${C}Delay`),n=A(i,`${C}Duration`),o=H(s,n),r=A(i,`${$}Delay`),a=A(i,`${$}Duration`),l=H(r,a);let h=null,c=0,u=0;return c=Math.max(o,l),h=c>0?o>l?C:$:null,u=h?h===C?n.length:a.length:0,{type:h,timeout:c,propCount:u}}(t);return!(!e||!i)&&new Promise(n=>{const o=`${e}end`,r=performance.now();let a=0;const l=()=>{t.removeEventListener(o,h),n()},h=e=>{if(e.target===t){if(!function(t){return[`${C}end`,`${$}end`].includes(t.type)}(e))throw new Error("Not a transition or animation event.");(performance.now()-r)/1e3<e.elapsedTime||++a>=s&&l()}};setTimeout(()=>{a<s&&l()},i+1),t.addEventListener(o,h)})}(t));s.filter(Boolean).length>0?await Promise.all(s):e&&console.warn(`[swup] No CSS animation duration defined on elements matching \`${e}\``)}function A(t,e){return(t[e]||"").split(", ")}function H(t,e){for(;t.length<e.length;)t=t.concat(t);return Math.max(...e.map((e,i)=>k(e)+k(t[i])))}function q(t,e={},s={}){if("string"!=typeof t)throw new Error("swup.navigate() requires a URL parameter");if(this.shouldIgnoreVisit(t,{el:s.el,event:s.event}))return void(window.location.href=t);const{url:n,hash:o}=l.fromUrl(t),r=this.createVisit(i({},s,{to:n,hash:o}));this.performNavigation(r,e)}async function V(t,e={}){if(this.navigating){if(this.visit.state>=6)return t.state=2,void(this.onVisitEnd=()=>this.performNavigation(t,e));await this.hooks.call("visit:abort",this.visit,void 0),this.visit.state=8}this.navigating=!0,this.visit=t;const{el:i}=t.trigger;e.referrer=e.referrer||this.currentPageUrl,!1===e.animate&&(t.animation.animate=!1),t.animation.animate||this.classes.clear();const a=e.history||(null==i?void 0:i.getAttribute("data-swup-history"))||void 0;a&&["push","replace"].includes(a)&&(t.history.action=a);const l=e.animation||(null==i?void 0:i.getAttribute("data-swup-animation"))||void 0;var h,c;l&&(t.animation.name=l),"object"==typeof e.cache?(t.cache.read=null!=(h=e.cache.read)?h:t.cache.read,t.cache.write=null!=(c=e.cache.write)?c:t.cache.write):void 0!==e.cache&&(t.cache={read:!!e.cache,write:!!e.cache}),delete e.cache;try{await this.hooks.call("visit:start",t,void 0),t.state=3;const i=this.hooks.call("page:load",t,{options:e},async(t,e)=>{let i;return t.cache.read&&(i=this.cache.get(t.to.url)),e.page=i||await this.fetchPage(t.to.url,e.options),e.cache=!!i,e.page});if(i.then(({html:e})=>{t.advance(5),t.to.html=e}),!t.history.popstate){const e=t.to.url+t.to.hash;"replace"===t.history.action||t.to.url===this.currentPageUrl?r(e):(this.currentHistoryIndex++,o(e,{index:this.currentHistoryIndex}))}if(this.currentPageUrl=n(),t.history.popstate&&this.classes.add("is-popstate"),t.animation.name&&this.classes.add(`to-${s(t.animation.name)}`),t.animation.wait&&await i,t.done)return;if(await this.hooks.call("visit:transition",t,void 0,async()=>{if(!t.animation.animate)return await this.hooks.call("animation:skip",void 0),void await this.renderPage(t,await i);t.advance(4),await this.animatePageOut(t),t.animation.native&&document.startViewTransition?await document.startViewTransition(async()=>await this.renderPage(t,await i)).finished:await this.renderPage(t,await i),await this.animatePageIn(t)}),t.done)return;await this.hooks.call("visit:end",t,void 0,()=>this.classes.clear()),t.state=7,this.navigating=!1,this.onVisitEnd&&(this.onVisitEnd(),this.onVisitEnd=void 0)}catch(e){if(!e||null!=e&&e.aborted)return void(t.state=8);t.state=9,console.error(e),this.options.skipPopStateHandling=()=>(window.location.href=t.to.url+t.to.hash,!0),window.history.go(-1)}}const I=async function(t){await this.hooks.call("animation:out:start",t,void 0,()=>{this.classes.add("is-changing","is-animating","is-leaving")}),await this.hooks.call("animation:out:await",t,{skip:!1},(t,{skip:e})=>{if(!e)return this.awaitAnimations({selector:t.animation.selector})}),await this.hooks.call("animation:out:end",t,void 0)},L=function({html:t},{containers:e}=this.options){var i;const s=(new DOMParser).parseFromString(t,"text/html"),n=(null==(i=s.querySelector("title"))?void 0:i.innerText)||"";document.title=n;const o=m('[data-swup-persist]:not([data-swup-persist=""])'),r=e.map(t=>{const e=document.querySelector(t),i=s.querySelector(t);return e&&i?(e.replaceWith(i),!0):(e||console.warn(`[swup] Container missing in current document: ${t}`),i||console.warn(`[swup] Container missing in incoming document: ${t}`),!1)}).filter(Boolean);return o.forEach(t=>{const e=t.getAttribute("data-swup-persist"),i=p(`[data-swup-persist="${e}"]`);i&&i!==t&&i.replaceWith(t)}),r.length===e.length},R=function(t){const e={behavior:"auto"},{target:s,reset:n}=t.scroll,o=null!=s?s:t.to.hash;let r=!1;return o&&(r=this.hooks.callSync("scroll:anchor",t,{hash:o,options:e},(t,{hash:e,options:i})=>{const s=this.getAnchorElement(e);return s&&s.scrollIntoView(i),!!s})),n&&!r&&(r=this.hooks.callSync("scroll:top",t,{options:e},(t,{options:e})=>(window.scrollTo(i({top:0,left:0},e)),!0))),r},T=async function(t){if(t.done)return;const e=this.hooks.call("animation:in:await",t,{skip:!1},(t,{skip:e})=>{if(!e)return this.awaitAnimations({selector:t.animation.selector})});await g(),await this.hooks.call("animation:in:start",t,void 0,()=>{this.classes.remove("is-animating")}),await e,await this.hooks.call("animation:in:end",t,void 0)},N=async function(t,e){if(t.done)return;t.advance(6);const{url:i}=e;this.classes.remove("is-leaving"),this.isSameResolvedUrl(n(),i)||(r(i),this.currentPageUrl=n(),t.to.url=this.currentPageUrl),t.animation.animate&&this.classes.add("is-rendering"),await this.hooks.call("content:replace",t,{page:e},(t,{page:e})=>{if(!this.replaceContent(e,{containers:t.containers}))throw new Error("[swup] Container mismatch, aborting");t.animation.animate&&(this.classes.add("is-changing","is-animating","is-rendering"),t.animation.name&&this.classes.add(`to-${s(t.animation.name)}`))}),await this.hooks.call("content:scroll",t,void 0,()=>this.scrollToContent(t)),await this.hooks.call("page:view",t,{url:this.currentPageUrl,title:document.title})},O=function(t){var e;if(e=t,Boolean(null==e?void 0:e.isSwupPlugin)){if(t.swup=this,!t._checkRequirements||t._checkRequirements())return t._beforeMount&&t._beforeMount(),t.mount(),this.plugins.push(t),this.plugins}else console.error("Not a swup plugin instance",t)};function D(t){const e=this.findPlugin(t);if(e)return e.unmount(),e._afterUnmount&&e._afterUnmount(),this.plugins=this.plugins.filter(t=>t!==e),this.plugins;console.error("No such plugin",e)}function M(t){return this.plugins.find(e=>e===t||e.name===t||e.name===`Swup${String(t)}`)}function W(t){if("function"!=typeof this.options.resolveUrl)return console.warn("[swup] options.resolveUrl expects a callback function."),t;const e=this.options.resolveUrl(t);return e&&"string"==typeof e?e.startsWith("//")||e.startsWith("http")?(console.warn("[swup] options.resolveUrl needs to return a relative url"),t):e:(console.warn("[swup] options.resolveUrl needs to return a url"),t)}function j(t,e){return this.resolveUrl(t)===this.resolveUrl(e)}const B={animateHistoryBrowsing:!1,animationSelector:'[class*="transition-"]',animationScope:"html",cache:!0,containers:["#swup"],ignoreVisit:(t,{el:e}={})=>!(null==e||!e.closest("[data-no-swup]")),linkSelector:"a[href]",linkToSelf:"scroll",native:!1,plugins:[],resolveUrl:t=>t,requestHeaders:{"X-Requested-With":"swup",Accept:"text/html, application/xhtml+xml"},skipPopStateHandling:t=>{var e;return"swup"!==(null==(e=t.state)?void 0:e.source)},timeout:0};class _{constructor(t={}){var e,s;this.version="4.5.0",this.options=void 0,this.defaults=B,this.plugins=[],this.visit=void 0,this.cache=void 0,this.hooks=void 0,this.classes=void 0,this.currentPageUrl=n(),this.currentHistoryIndex=void 0,this.clickDelegate=void 0,this.navigating=!1,this.onVisitEnd=void 0,this.use=O,this.unuse=D,this.findPlugin=M,this.log=()=>{},this.navigate=q,this.performNavigation=V,this.createVisit=E,this.delegateEvent=a,this.fetchPage=u,this.awaitAnimations=x,this.renderPage=N,this.replaceContent=L,this.animatePageIn=T,this.animatePageOut=I,this.scrollToContent=R,this.getAnchorElement=U,this.getCurrentUrl=n,this.resolveUrl=W,this.isSameResolvedUrl=j,this.options=i({},this.defaults,t),this.handleLinkClick=this.handleLinkClick.bind(this),this.handlePopState=this.handlePopState.bind(this),this.cache=new d(this),this.classes=new b(this),this.hooks=new P(this),this.visit=this.createVisit({to:""}),this.currentHistoryIndex=null!=(e=null==(s=history.state)?void 0:s.index)?e:1,this.checkRequirements()&&this.enable()}checkRequirements(){return"undefined"!=typeof Promise||(console.warn("Promise is not supported"),!1)}async enable(){var t;const{linkSelector:e}=this.options;this.clickDelegate=this.delegateEvent(e,"click",this.handleLinkClick),window.addEventListener("popstate",this.handlePopState),this.options.animateHistoryBrowsing&&(window.history.scrollRestoration="manual"),this.options.native=this.options.native&&!!document.startViewTransition,this.options.plugins.forEach(t=>this.use(t)),"swup"!==(null==(t=history.state)?void 0:t.source)&&r(null,{index:this.currentHistoryIndex}),await g(),await this.hooks.call("enable",void 0,void 0,()=>{const t=document.documentElement;t.classList.add("swup-enabled"),t.classList.toggle("swup-native",this.options.native)})}async destroy(){this.clickDelegate.destroy(),window.removeEventListener("popstate",this.handlePopState),this.cache.clear(),this.options.plugins.forEach(t=>this.unuse(t)),await this.hooks.call("disable",void 0,void 0,()=>{const t=document.documentElement;t.classList.remove("swup-enabled"),t.classList.remove("swup-native")}),this.hooks.clear()}shouldIgnoreVisit(t,{el:e,event:i}={}){const{origin:s,url:n,hash:o}=l.fromUrl(t);return s!==window.location.origin||!(!e||!this.triggerWillOpenNewWindow(e))||!!this.options.ignoreVisit(n+o,{el:e,event:i})}handleLinkClick(t){const e=t.delegateTarget,{href:i,url:s,hash:n}=l.fromElement(e);if(this.shouldIgnoreVisit(i,{el:e,event:t}))return;if(this.navigating&&s===this.visit.to.url)return void t.preventDefault();const o=this.createVisit({to:s,hash:n,el:e,event:t});t.metaKey||t.ctrlKey||t.shiftKey||t.altKey?this.hooks.callSync("link:newtab",o,{href:i}):0===t.button&&this.hooks.callSync("link:click",o,{el:e,event:t},()=>{var e;const i=null!=(e=o.from.url)?e:"";t.preventDefault(),s&&s!==i?this.isSameResolvedUrl(s,i)||this.performNavigation(o):n?this.hooks.callSync("link:anchor",o,{hash:n},()=>{r(s+n),this.scrollToContent(o)}):this.hooks.callSync("link:self",o,void 0,()=>{"navigate"===this.options.linkToSelf?this.performNavigation(o):(r(s),this.scrollToContent(o))})})}handlePopState(t){var e,i,s,o;const r=null!=(e=null==(i=t.state)?void 0:i.url)?e:location.href;if(this.options.skipPopStateHandling(t))return;if(this.isSameResolvedUrl(n(),this.currentPageUrl))return;const{url:a,hash:h}=l.fromUrl(r),c=this.createVisit({to:a,hash:h,event:t});c.history.popstate=!0;const u=null!=(s=null==(o=t.state)?void 0:o.index)?s:0;u&&u!==this.currentHistoryIndex&&(c.history.direction=u-this.currentHistoryIndex>0?"forwards":"backwards",this.currentHistoryIndex=u),c.animation.animate=!1,c.scroll.reset=!1,c.scroll.target=!1,this.options.animateHistoryBrowsing&&(c.animation.animate=!0,c.scroll.reset=!0),this.hooks.callSync("history:popstate",c,{event:t},()=>{this.performNavigation(c)})}triggerWillOpenNewWindow(t){return!!t.matches('[download], [target="_blank"]')}}export{l as Location,s as classify,o as createHistoryRecord,_ as default,a as delegateEvent,y as escapeCssIdentifier,w as forceReflow,n as getCurrentUrl,f as isPromise,h as matchPath,g as nextTick,p as query,m as queryAll,v as runAsPromise,k as toMs,r as updateHistoryRecord}; | ||
//# sourceMappingURL=Swup.modern.js.map |
@@ -1,2 +0,2 @@ | ||
import t from"delegate-it";import{match as e}from"path-to-regexp";const n=(t,e)=>String(t).toLowerCase().replace(/[\s/_.]+/g,"-").replace(/[^\w-]+/g,"").replace(/--+/g,"-").replace(/^-+|-+$/g,"")||e||"",r=({hash:t}={})=>location.pathname+location.search+(t?location.hash:""),o=(t,e={})=>{const n={url:t=t||r({hash:!0}),random:Math.random(),source:"swup",...e};history.pushState(n,"",t)},i=(t=null,e={})=>{t=t||r({hash:!0});const n={...history.state||{},url:t,random:Math.random(),source:"swup",...e};history.replaceState(n,"",t)},s=(e,n,r,o)=>{const i=new AbortController;return o={...o,signal:i.signal},t(e,n,r,o),{destroy:()=>i.abort()}};class a extends URL{constructor(t,e=document.baseURI){super(t.toString(),e),Object.setPrototypeOf(this,a.prototype)}get url(){return this.pathname+this.search}static fromElement(t){const e=t.getAttribute("href")||t.getAttribute("xlink:href")||"";return new a(e)}static fromUrl(t){return new a(t)}}const c=(t,n)=>{try{return e(t,n)}catch(e){throw new Error(`[swup] Error parsing path "${String(t)}":\n${String(e)}`)}},l=function(t,e={}){try{const r=this;function n(n){const{status:o,url:i}=l;return Promise.resolve(l.text()).then(function(n){if(500===o)throw r.hooks.call("fetch:error",{status:o,response:l,url:i}),new h(`Server error: ${i}`,{status:o,url:i});if(!n)throw new h(`Empty response: ${i}`,{status:o,url:i});const{url:s}=a.fromUrl(i),c={url:s,html:n};return!r.visit.cache.write||e.method&&"GET"!==e.method||t!==s||r.cache.set(c.url,c),c})}t=a.fromUrl(t).url;const o={...r.options.requestHeaders,...e.headers},i=e.timeout??r.options.timeout,s=new AbortController,{signal:c}=s;e={...e,headers:o,signal:c};let l,u=!1,m=null;i&&i>0&&(m=setTimeout(()=>{u=!0,s.abort("timeout")},i));const d=function(n,o){try{var i=Promise.resolve(r.hooks.call("fetch:request",{url:t,options:e},(t,{url:e,options:n})=>fetch(e,n))).then(function(t){l=t,m&&clearTimeout(m)})}catch(t){return o(t)}return i&&i.then?i.then(void 0,o):i}(0,function(e){if(u)throw r.hooks.call("fetch:timeout",{url:t}),new h(`Request timed out: ${t}`,{url:t,timedOut:u});if("AbortError"===e?.name||c.aborted)throw new h(`Request aborted: ${t}`,{url:t,aborted:!0});throw e});return Promise.resolve(d&&d.then?d.then(n):n())}catch(p){return Promise.reject(p)}};class h extends Error{constructor(t,e){super(t),this.url=void 0,this.status=void 0,this.aborted=void 0,this.timedOut=void 0,this.name="FetchError",this.url=e.url,this.status=e.status,this.aborted=e.aborted||!1,this.timedOut=e.timedOut||!1}}class u{constructor(t){this.swup=void 0,this.pages=new Map,this.swup=t}get size(){return this.pages.size}get all(){const t=new Map;return this.pages.forEach((e,n)=>{t.set(n,{...e})}),t}has(t){return this.pages.has(this.resolve(t))}get(t){const e=this.pages.get(this.resolve(t));return e?{...e}:e}set(t,e){t=this.resolve(t),e={...e,url:t},this.pages.set(t,e),this.swup.hooks.callSync("cache:set",{page:e})}update(t,e){t=this.resolve(t);const n={...this.get(t),...e,url:t};this.pages.set(t,n)}delete(t){this.pages.delete(this.resolve(t))}clear(){this.pages.clear(),this.swup.hooks.callSync("cache:clear",void 0)}prune(t){this.pages.forEach((e,n)=>{t(n,e)&&this.delete(n)})}resolve(t){const{url:e}=a.fromUrl(t);return this.swup.resolveUrl(e)}}const m=(t,e=document)=>e.querySelector(t),d=(t,e=document)=>Array.from(e.querySelectorAll(t)),p=()=>new Promise(t=>{requestAnimationFrame(()=>{requestAnimationFrame(()=>{t()})})});function f(t){return!!t&&("object"==typeof t||"function"==typeof t)&&"function"==typeof t.then}function v(t,e=[]){return new Promise((n,r)=>{const o=t(...e);f(o)?o.then(n,r):n(o)})}function g(t){return t=t||document.body,t?.offsetHeight}const w=t=>window.CSS&&window.CSS.escape?CSS.escape(t):t,y=t=>1e3*Number(t.slice(0,-1).replace(",","."));class P{constructor(t){this.swup=void 0,this.swupClasses=["to-","is-changing","is-rendering","is-popstate","is-animating"],this.swup=t}get selectors(){const{scope:t}=this.swup.visit.animation;return"containers"===t?this.swup.visit.containers:"html"===t?["html"]:Array.isArray(t)?t:[]}get selector(){return this.selectors.join(",")}get targets(){return this.selector.trim()?d(this.selector):[]}add(){this.targets.forEach(t=>t.classList.add(...[].slice.call(arguments)))}remove(){this.targets.forEach(t=>t.classList.remove(...[].slice.call(arguments)))}clear(){this.targets.forEach(t=>{const e=t.className.split(" ").filter(t=>this.isSwupClass(t));t.classList.remove(...e)})}isSwupClass(t){return this.swupClasses.some(e=>t.startsWith(e))}}function k({to:t,from:e=this.currentPageUrl,hash:n,el:r,event:o}){return{id:Math.random(),from:{url:e},to:{url:t,hash:n},containers:this.options.containers,animation:{animate:!0,wait:!1,name:void 0,scope:this.options.animationScope,selector:this.options.animationSelector},trigger:{el:r,event:o},cache:{read:this.options.cache,write:this.options.cache},history:{action:"push",popstate:!1,direction:void 0},scroll:{reset:!0,target:void 0}}}const b="undefined"!=typeof Symbol?Symbol.iterator||(Symbol.iterator=Symbol("Symbol.iterator")):"@@iterator";function S(t,e,n){if(!t.s){if(n instanceof E){if(!n.s)return void(n.o=S.bind(null,t,e));1&e&&(e=n.s),n=n.v}if(n&&n.then)return void n.then(S.bind(null,t,e),S.bind(null,t,2));t.s=e,t.v=n;const r=t.o;r&&r(t)}}const E=/*#__PURE__*/function(){function t(){}return t.prototype.then=function(e,n){const r=new t,o=this.s;if(o){const t=1&o?e:n;if(t){try{S(r,1,t(this.v))}catch(t){S(r,2,t)}return r}return this}return this.o=function(t){try{const o=t.v;1&t.s?S(r,1,e?e(o):o):n?S(r,1,n(o)):S(r,2,o)}catch(t){S(r,2,t)}},r},t}();function U(t){return t instanceof E&&1&t.s}class C{constructor(t){this.swup=void 0,this.registry=new Map,this.hooks=["animation:out:start","animation:out:await","animation:out:end","animation:in:start","animation:in:await","animation:in:end","animation:skip","cache:clear","cache:set","content:replace","content:scroll","enable","disable","fetch:request","fetch:error","fetch:timeout","history:popstate","link:click","link:self","link:anchor","link:newtab","page:load","page:view","scroll:top","scroll:anchor","visit:start","visit:transition","visit:end"],this.swup=t,this.init()}init(){this.hooks.forEach(t=>this.create(t))}create(t){this.registry.has(t)||this.registry.set(t,new Map)}exists(t){return this.registry.has(t)}get(t){const e=this.registry.get(t);if(e)return e;console.error(`Unknown hook '${t}'`)}clear(){this.registry.forEach(t=>t.clear())}on(t,e,n={}){const r=this.get(t);if(!r)return console.warn(`Hook '${t}' not found.`),()=>{};const o={...n,id:r.size+1,hook:t,handler:e};return r.set(e,o),()=>this.off(t,e)}before(t,e,n={}){return this.on(t,e,{...n,before:!0})}replace(t,e,n={}){return this.on(t,e,{...n,replace:!0})}once(t,e,n={}){return this.on(t,e,{...n,once:!0})}off(t,e){const n=this.get(t);n&&e?n.delete(e)||console.warn(`Handler for hook '${t}' not found.`):n&&n.clear()}call(t,e,n){try{const r=this,{before:o,handler:i,after:s}=r.getHandlers(t,n);return Promise.resolve(r.run(o,e)).then(function(){return Promise.resolve(r.run(i,e)).then(function([n]){return Promise.resolve(r.run(s,e)).then(function(){return r.dispatchDomEvent(t,e),n})})})}catch(t){return Promise.reject(t)}}callSync(t,e,n){const{before:r,handler:o,after:i}=this.getHandlers(t,n);this.runSync(r,e);const[s]=this.runSync(o,e);return this.runSync(i,e),this.dispatchDomEvent(t,e),s}run(t,e){try{const n=this,r=[],o=function(t,e,n){if("function"==typeof t[b]){var r,o,i,s=t[b]();if(function t(n){try{for(;!(r=s.next()).done;)if((n=e(r.value))&&n.then){if(!U(n))return void n.then(t,i||(i=S.bind(null,o=new E,2)));n=n.v}o?S(o,1,n):o=n}catch(t){S(o||(o=new E),2,t)}}(),s.return){var a=function(t){try{r.done||s.return()}catch(t){}return t};if(o&&o.then)return o.then(a,function(t){throw a(t)});a()}return o}if(!("length"in t))throw new TypeError("Object is not iterable");for(var c=[],l=0;l<t.length;l++)c.push(t[l]);return function(t,e,n){var r,o,i=-1;return function n(s){try{for(;++i<t.length;)if((s=e(i))&&s.then){if(!U(s))return void s.then(n,o||(o=S.bind(null,r=new E,2)));s=s.v}r?S(r,1,s):r=s}catch(t){S(r||(r=new E),2,t)}}(),r}(c,function(t){return e(c[t])})}(t,function({hook:t,handler:o,defaultHandler:i,once:s}){return Promise.resolve(v(o,[n.swup.visit,e,i])).then(function(e){r.push(e),s&&n.off(t,o)})});return Promise.resolve(o&&o.then?o.then(function(){return r}):r)}catch(t){return Promise.reject(t)}}runSync(t,e){const n=[];for(const{hook:r,handler:o,defaultHandler:i,once:s}of t){const t=o(this.swup.visit,e,i);n.push(t),f(t)&&console.warn(`Promise returned from handler for synchronous hook '${r}'.Swup will not wait for it to resolve.`),s&&this.off(r,o)}return n}getHandlers(t,e){const n=this.get(t);if(!n)return{found:!1,before:[],handler:[],after:[],replaced:!1};const r=Array.from(n.values()),o=this.sortRegistrations,i=r.filter(({before:t,replace:e})=>t&&!e).sort(o),s=r.filter(({replace:t})=>t).filter(t=>!0).sort(o),a=r.filter(({before:t,replace:e})=>!t&&!e).sort(o),c=s.length>0;let l=[];if(e&&(l=[{id:0,hook:t,handler:e}],c)){const n=s.length-1,r=t=>{const n=s[t-1];return n?(e,o)=>n.handler(e,o,r(t-1)):e};l=[{id:0,hook:t,handler:s[n].handler,defaultHandler:r(n)}]}return{found:!0,before:i,handler:l,after:a,replaced:c}}sortRegistrations(t,e){return(t.priority??0)-(e.priority??0)||t.id-e.id||0}dispatchDomEvent(t,e){const n={hook:t,args:e,visit:this.swup.visit};document.dispatchEvent(new CustomEvent("swup:any",{detail:n,bubbles:!0})),document.dispatchEvent(new CustomEvent(`swup:${t}`,{detail:n,bubbles:!0}))}}const $=t=>{if(t&&"#"===t.charAt(0)&&(t=t.substring(1)),!t)return null;const e=decodeURIComponent(t);let n=document.getElementById(t)||document.getElementById(e)||m(`a[name='${w(t)}']`)||m(`a[name='${w(e)}']`);return n||"top"!==t||(n=document.body),n},x=function({elements:t,selector:e}){try{if(!1===e&&!t)return Promise.resolve();let n=[];if(t)n=Array.from(t);else if(e&&(n=d(e,document.body),!n.length))return console.warn(`[swup] No elements found matching animationSelector \`${e}\``),Promise.resolve();const r=n.map(t=>function(t){const{type:e,timeout:n,propCount:r}=function(t,e){const n=window.getComputedStyle(t),r=j(n,`${H}Delay`),o=j(n,`${H}Duration`),i=q(r,o),s=j(n,`${A}Delay`),a=j(n,`${A}Duration`),c=q(s,a);let l=null,h=0,u=0;return e===H?i>0&&(l=H,h=i,u=o.length):e===A?c>0&&(l=A,h=c,u=a.length):(h=Math.max(i,c),l=h>0?i>c?H:A:null,u=l?l===H?o.length:a.length:0),{type:l,timeout:h,propCount:u}}(t);return!(!e||!n)&&new Promise(o=>{const i=`${e}end`,s=performance.now();let a=0;const c=()=>{t.removeEventListener(i,l),o()},l=e=>{if(e.target===t){if(!function(t){return[`${H}end`,`${A}end`].includes(t.type)}(e))throw new Error("Not a transition or animation event.");(performance.now()-s)/1e3<e.elapsedTime||++a>=r&&c()}};setTimeout(()=>{a<r&&c()},n+1),t.addEventListener(i,l)})}(t));return r.filter(Boolean).length>0?Promise.resolve(Promise.all(r)).then(function(){}):(e&&console.warn(`[swup] No CSS animation duration defined on elements matching \`${e}\``),Promise.resolve())}catch(t){return Promise.reject(t)}},H="transition",A="animation";function j(t,e){return(t[e]||"").split(", ")}function q(t,e){for(;t.length<e.length;)t=t.concat(t);return Math.max(...e.map((e,n)=>y(e)+y(t[n])))}const I=function(t={}){try{const e=this;e.navigating=!0;const n=e.visit,{el:s}=n.trigger;t.referrer=t.referrer||e.currentPageUrl,!1===t.animate&&(n.animation.animate=!1),n.animation.animate||e.classes.clear();const a=t.history||s?.getAttribute("data-swup-history")||void 0;a&&["push","replace"].includes(a)&&(n.history.action=a);const c=t.animation||s?.getAttribute("data-swup-animation")||void 0;return c&&(n.animation.name=c),"object"==typeof t.cache?(n.cache.read=t.cache.read??n.cache.read,n.cache.write=t.cache.write??n.cache.write):void 0!==t.cache&&(n.cache={read:!!t.cache,write:!!t.cache}),delete t.cache,Promise.resolve(function(s,a){try{var c=Promise.resolve(e.hooks.call("visit:start",void 0)).then(function(){function s(){return Promise.resolve(e.hooks.call("visit:transition",void 0,function(t){try{const n=e.animatePageOut();return Promise.resolve(Promise.all([a,n])).then(function([n]){return t.id===e.visit.id&&Promise.resolve(e.renderPage(n)).then(function(){return Promise.resolve(e.animatePageIn()).then(function(){return!0})})})}catch(t){return Promise.reject(t)}})).then(function(){return Promise.resolve(e.hooks.call("visit:end",void 0,()=>e.classes.clear())).then(function(){e.navigating=!1})})}const a=e.hooks.call("page:load",{options:t},function(t,n){try{function r(t){return n.page=t,n.cache=!!o,n.page}let o;return t.cache.read&&(o=e.cache.get(t.to.url)),Promise.resolve(o?r(o):Promise.resolve(e.fetchPage(t.to.url,n.options)).then(r))}catch(i){return Promise.reject(i)}});if(!n.history.popstate){const t=n.to.url+n.to.hash;"replace"===n.history.action||n.to.url===e.currentPageUrl?i(t):(e.currentHistoryIndex++,o(t,{index:e.currentHistoryIndex}))}e.currentPageUrl=r();const c=function(){if(n.animation.wait)return Promise.resolve(a).then(function({html:t}){n.to.html=t})}();return c&&c.then?c.then(s):s()})}catch(t){return a(t)}return c&&c.then?c.then(void 0,a):c}(0,function(t){t&&!t?.aborted&&(console.error(t),e.options.skipPopStateHandling=()=>(window.location.href=n.to.url+n.to.hash,!0),window.history.go(-1))}))}catch(t){return Promise.reject(t)}};function R(t,e={},n={}){if("string"!=typeof t)throw new Error("swup.navigate() requires a URL parameter");if(this.shouldIgnoreVisit(t,{el:n.el,event:n.event}))return void(window.location.href=t);const{url:r,hash:o}=a.fromUrl(t);this.visit=this.createVisit({...n,to:r,hash:o}),this.performNavigation(e)}const L=function(){try{let e;const r=this;function t(t){return e?t:Promise.resolve(r.hooks.call("animation:out:start",void 0,t=>{r.classes.add("is-changing","is-leaving","is-animating"),t.history.popstate&&r.classes.add("is-popstate"),t.animation.name&&r.classes.add(`to-${n(t.animation.name)}`)})).then(function(){return Promise.resolve(r.hooks.call("animation:out:await",{skip:!1},function(t,{skip:e}){try{return e?Promise.resolve():Promise.resolve(r.awaitAnimations({selector:t.animation.selector})).then(function(){})}catch(t){return Promise.reject(t)}})).then(function(){return Promise.resolve(r.hooks.call("animation:out:end",void 0)).then(function(){})})})}const o=function(){if(!r.visit.animation.animate)return Promise.resolve(r.hooks.call("animation:skip",void 0)).then(function(){e=1})}();return Promise.resolve(o&&o.then?o.then(t):t(o))}catch(i){return Promise.reject(i)}},T=function({html:t},{containers:e}=this.options){const n=(new DOMParser).parseFromString(t,"text/html"),r=n.querySelector("title")?.innerText||"";document.title=r;const o=d('[data-swup-persist]:not([data-swup-persist=""])'),i=e.map(t=>{const e=document.querySelector(t),r=n.querySelector(t);return e&&r?(e.replaceWith(r),!0):(e||console.warn(`[swup] Container missing in current document: ${t}`),r||console.warn(`[swup] Container missing in incoming document: ${t}`),!1)}).filter(Boolean);return o.forEach(t=>{const e=t.getAttribute("data-swup-persist"),n=m(`[data-swup-persist="${e}"]`);n&&n!==t&&n.replaceWith(t)}),i.length===e.length},N=function(){const t={behavior:"auto"},{target:e,reset:n}=this.visit.scroll,r=e??this.visit.to.hash;let o=!1;return r&&(o=this.hooks.callSync("scroll:anchor",{hash:r,options:t},(t,{hash:e,options:n})=>{const r=this.getAnchorElement(e);return r&&r.scrollIntoView(n),!!r})),n&&!o&&(o=this.hooks.callSync("scroll:top",{options:t},(t,{options:e})=>(window.scrollTo({top:0,left:0,...e}),!0))),o},D=function(){try{const t=this;if(!t.visit.animation.animate)return Promise.resolve();const e=t.hooks.call("animation:in:await",{skip:!1},function(e,{skip:n}){try{return n?Promise.resolve():Promise.resolve(t.awaitAnimations({selector:e.animation.selector})).then(function(){})}catch(t){return Promise.reject(t)}});return Promise.resolve(p()).then(function(){return Promise.resolve(t.hooks.call("animation:in:start",void 0,()=>{t.classes.remove("is-animating")})).then(function(){return Promise.resolve(e).then(function(){return Promise.resolve(t.hooks.call("animation:in:end",void 0)).then(function(){})})})})}catch(t){return Promise.reject(t)}},M=function(t){try{const e=this,{url:o,html:s}=t;return e.classes.remove("is-leaving"),e.isSameResolvedUrl(r(),o)||(i(o),e.currentPageUrl=r(),e.visit.to.url=e.currentPageUrl),e.visit.animation.animate&&e.classes.add("is-rendering"),e.visit.to.html=s,Promise.resolve(e.hooks.call("content:replace",{page:t},(t,{page:r})=>{if(!e.replaceContent(r,{containers:t.containers}))throw new Error("[swup] Container mismatch, aborting");t.animation.animate&&(e.classes.add("is-animating","is-changing","is-rendering"),t.animation.name&&e.classes.add(`to-${n(t.animation.name)}`))})).then(function(){return Promise.resolve(e.hooks.call("content:scroll",void 0,()=>e.scrollToContent())).then(function(){return Promise.resolve(e.hooks.call("page:view",{url:e.currentPageUrl,title:document.title})).then(function(){})})})}catch(t){return Promise.reject(t)}},O=function(t){var e;if(e=t,Boolean(e?.isSwupPlugin)){if(t.swup=this,!t._checkRequirements||t._checkRequirements())return t._beforeMount&&t._beforeMount(),t.mount(),this.plugins.push(t),this.plugins}else console.error("Not a swup plugin instance",t)};function V(t){const e=this.findPlugin(t);if(e)return e.unmount(),e._afterUnmount&&e._afterUnmount(),this.plugins=this.plugins.filter(t=>t!==e),this.plugins;console.error("No such plugin",e)}function W(t){return this.plugins.find(e=>e===t||e.name===t||e.name===`Swup${String(t)}`)}function B(t){if("function"!=typeof this.options.resolveUrl)return console.warn("[swup] options.resolveUrl expects a callback function."),t;const e=this.options.resolveUrl(t);return e&&"string"==typeof e?e.startsWith("//")||e.startsWith("http")?(console.warn("[swup] options.resolveUrl needs to return a relative url"),t):e:(console.warn("[swup] options.resolveUrl needs to return a url"),t)}function _(t,e){return this.resolveUrl(t)===this.resolveUrl(e)}const F={animateHistoryBrowsing:!1,animationSelector:'[class*="transition-"]',animationScope:"html",cache:!0,containers:["#swup"],ignoreVisit:(t,{el:e}={})=>!!e?.closest("[data-no-swup]"),linkSelector:"a[href]",linkToSelf:"scroll",plugins:[],resolveUrl:t=>t,requestHeaders:{"X-Requested-With":"swup",Accept:"text/html, application/xhtml+xml"},skipPopStateHandling:t=>"swup"!==t.state?.source,timeout:0};class K{constructor(t={}){this.version="4.4.4",this.options=void 0,this.defaults=F,this.plugins=[],this.visit=void 0,this.cache=void 0,this.hooks=void 0,this.classes=void 0,this.currentPageUrl=r(),this.currentHistoryIndex=void 0,this.clickDelegate=void 0,this.navigating=!1,this.use=O,this.unuse=V,this.findPlugin=W,this.log=()=>{},this.navigate=R,this.performNavigation=I,this.createVisit=k,this.delegateEvent=s,this.fetchPage=l,this.awaitAnimations=x,this.renderPage=M,this.replaceContent=T,this.animatePageIn=D,this.animatePageOut=L,this.scrollToContent=N,this.getAnchorElement=$,this.getCurrentUrl=r,this.resolveUrl=B,this.isSameResolvedUrl=_,this.options={...this.defaults,...t},this.handleLinkClick=this.handleLinkClick.bind(this),this.handlePopState=this.handlePopState.bind(this),this.cache=new u(this),this.classes=new P(this),this.hooks=new C(this),this.visit=this.createVisit({to:""}),this.currentHistoryIndex=history.state?.index??1,this.checkRequirements()&&this.enable()}checkRequirements(){return"undefined"!=typeof Promise||(console.warn("Promise is not supported"),!1)}enable(){try{const t=this,{linkSelector:e}=t.options;return t.clickDelegate=t.delegateEvent(e,"click",t.handleLinkClick),window.addEventListener("popstate",t.handlePopState),t.options.animateHistoryBrowsing&&(window.history.scrollRestoration="manual"),t.options.plugins.forEach(e=>t.use(e)),"swup"!==history.state?.source&&i(null,{index:t.currentHistoryIndex}),Promise.resolve(p()).then(function(){return Promise.resolve(t.hooks.call("enable",void 0,()=>{document.documentElement.classList.add("swup-enabled")})).then(function(){})})}catch(t){return Promise.reject(t)}}destroy(){try{const t=this;return t.clickDelegate.destroy(),window.removeEventListener("popstate",t.handlePopState),t.cache.clear(),t.options.plugins.forEach(e=>t.unuse(e)),Promise.resolve(t.hooks.call("disable",void 0,()=>{document.documentElement.classList.remove("swup-enabled")})).then(function(){t.hooks.clear()})}catch(t){return Promise.reject(t)}}shouldIgnoreVisit(t,{el:e,event:n}={}){const{origin:r,url:o,hash:i}=a.fromUrl(t);return r!==window.location.origin||!(!e||!this.triggerWillOpenNewWindow(e))||!!this.options.ignoreVisit(o+i,{el:e,event:n})}handleLinkClick(t){const e=t.delegateTarget,{href:n,url:r,hash:o}=a.fromElement(e);this.shouldIgnoreVisit(n,{el:e,event:t})||(this.navigating&&r===this.visit.to.url?t.preventDefault():(this.visit=this.createVisit({to:r,hash:o,el:e,event:t}),t.metaKey||t.ctrlKey||t.shiftKey||t.altKey?this.hooks.call("link:newtab",{href:n}):0===t.button&&this.hooks.callSync("link:click",{el:e,event:t},()=>{const e=this.visit.from.url??"";t.preventDefault(),r&&r!==e?this.isSameResolvedUrl(r,e)||this.performNavigation():o?this.hooks.callSync("link:anchor",{hash:o},()=>{i(r+o),this.scrollToContent()}):this.hooks.callSync("link:self",void 0,()=>"navigate"===this.options.linkToSelf?this.performNavigation():(i(r),this.scrollToContent()))})))}handlePopState(t){const e=t.state?.url??location.href;if(this.options.skipPopStateHandling(t))return;if(this.isSameResolvedUrl(r(),this.currentPageUrl))return;const{url:n,hash:o}=a.fromUrl(e);this.visit=this.createVisit({to:n,hash:o,event:t}),this.visit.history.popstate=!0;const i=t.state?.index??0;i&&i!==this.currentHistoryIndex&&(this.visit.history.direction=i-this.currentHistoryIndex>0?"forwards":"backwards",this.currentHistoryIndex=i),this.visit.animation.animate=!1,this.visit.scroll.reset=!1,this.visit.scroll.target=!1,this.options.animateHistoryBrowsing&&(this.visit.animation.animate=!0,this.visit.scroll.reset=!0),this.hooks.callSync("history:popstate",{event:t},()=>{this.performNavigation()})}triggerWillOpenNewWindow(t){return!!t.matches('[download], [target="_blank"]')}}export{a as Location,n as classify,o as createHistoryRecord,K as default,s as delegateEvent,w as escapeCssIdentifier,g as forceReflow,r as getCurrentUrl,f as isPromise,c as matchPath,p as nextTick,m as query,d as queryAll,v as runAsPromise,y as toMs,i as updateHistoryRecord}; | ||
import t from"delegate-it";import{match as e}from"path-to-regexp";const n=(t,e)=>String(t).toLowerCase().replace(/[\s/_.]+/g,"-").replace(/[^\w-]+/g,"").replace(/--+/g,"-").replace(/^-+|-+$/g,"")||e||"",r=({hash:t}={})=>location.pathname+location.search+(t?location.hash:""),o=(t,e={})=>{const n={url:t=t||r({hash:!0}),random:Math.random(),source:"swup",...e};history.pushState(n,"",t)},i=(t=null,e={})=>{t=t||r({hash:!0});const n={...history.state||{},url:t,random:Math.random(),source:"swup",...e};history.replaceState(n,"",t)},s=(e,n,r,o)=>{const i=new AbortController;return o={...o,signal:i.signal},t(e,n,r,o),{destroy:()=>i.abort()}};class a extends URL{constructor(t,e=document.baseURI){super(t.toString(),e),Object.setPrototypeOf(this,a.prototype)}get url(){return this.pathname+this.search}static fromElement(t){const e=t.getAttribute("href")||t.getAttribute("xlink:href")||"";return new a(e)}static fromUrl(t){return new a(t)}}const c=(t,n)=>{try{return e(t,n)}catch(e){throw new Error(`[swup] Error parsing path "${String(t)}":\n${String(e)}`)}},l=function(t,e={}){try{const r=this;function n(n){const{status:i,url:s}=u;return Promise.resolve(u.text()).then(function(n){if(500===i)throw r.hooks.call("fetch:error",o,{status:i,response:u,url:s}),new h(`Server error: ${s}`,{status:i,url:s});if(!n)throw new h(`Empty response: ${s}`,{status:i,url:s});const{url:c}=a.fromUrl(s),l={url:c,html:n};return!o.cache.write||e.method&&"GET"!==e.method||t!==c||r.cache.set(l.url,l),l})}t=a.fromUrl(t).url;const{visit:o=r.visit}=e,i={...r.options.requestHeaders,...e.headers},s=e.timeout??r.options.timeout,c=new AbortController,{signal:l}=c;e={...e,headers:i,signal:l};let u,d=!1,m=null;s&&s>0&&(m=setTimeout(()=>{d=!0,c.abort("timeout")},s));const f=function(n,i){try{var s=Promise.resolve(r.hooks.call("fetch:request",o,{url:t,options:e},(t,{url:e,options:n})=>fetch(e,n))).then(function(t){u=t,m&&clearTimeout(m)})}catch(t){return i(t)}return s&&s.then?s.then(void 0,i):s}(0,function(e){if(d)throw r.hooks.call("fetch:timeout",o,{url:t}),new h(`Request timed out: ${t}`,{url:t,timedOut:d});if("AbortError"===e?.name||l.aborted)throw new h(`Request aborted: ${t}`,{url:t,aborted:!0});throw e});return Promise.resolve(f&&f.then?f.then(n):n())}catch(p){return Promise.reject(p)}};class h extends Error{constructor(t,e){super(t),this.url=void 0,this.status=void 0,this.aborted=void 0,this.timedOut=void 0,this.name="FetchError",this.url=e.url,this.status=e.status,this.aborted=e.aborted||!1,this.timedOut=e.timedOut||!1}}class u{constructor(t){this.swup=void 0,this.pages=new Map,this.swup=t}get size(){return this.pages.size}get all(){const t=new Map;return this.pages.forEach((e,n)=>{t.set(n,{...e})}),t}has(t){return this.pages.has(this.resolve(t))}get(t){const e=this.pages.get(this.resolve(t));return e?{...e}:e}set(t,e){t=this.resolve(t),e={...e,url:t},this.pages.set(t,e),this.swup.hooks.callSync("cache:set",void 0,{page:e})}update(t,e){t=this.resolve(t);const n={...this.get(t),...e,url:t};this.pages.set(t,n)}delete(t){this.pages.delete(this.resolve(t))}clear(){this.pages.clear(),this.swup.hooks.callSync("cache:clear",void 0,void 0)}prune(t){this.pages.forEach((e,n)=>{t(n,e)&&this.delete(n)})}resolve(t){const{url:e}=a.fromUrl(t);return this.swup.resolveUrl(e)}}const d=(t,e=document)=>e.querySelector(t),m=(t,e=document)=>Array.from(e.querySelectorAll(t)),f=()=>new Promise(t=>{requestAnimationFrame(()=>{requestAnimationFrame(()=>{t()})})});function p(t){return!!t&&("object"==typeof t||"function"==typeof t)&&"function"==typeof t.then}function v(t,e=[]){return new Promise((n,r)=>{const o=t(...e);p(o)?o.then(n,r):n(o)})}function g(t){return t=t||document.body,t?.offsetHeight}const w=t=>window.CSS&&window.CSS.escape?CSS.escape(t):t,y=t=>1e3*Number(t.slice(0,-1).replace(",","."));class P{constructor(t){this.swup=void 0,this.swupClasses=["to-","is-changing","is-rendering","is-popstate","is-animating","is-leaving"],this.swup=t}get selectors(){const{scope:t}=this.swup.visit.animation;return"containers"===t?this.swup.visit.containers:"html"===t?["html"]:Array.isArray(t)?t:[]}get selector(){return this.selectors.join(",")}get targets(){return this.selector.trim()?m(this.selector):[]}add(){this.targets.forEach(t=>t.classList.add(...[].slice.call(arguments)))}remove(){this.targets.forEach(t=>t.classList.remove(...[].slice.call(arguments)))}clear(){this.targets.forEach(t=>{const e=t.className.split(" ").filter(t=>this.isSwupClass(t));t.classList.remove(...e)})}isSwupClass(t){return this.swupClasses.some(e=>t.startsWith(e))}}class k{constructor(t,e){this.id=void 0,this.state=void 0,this.from=void 0,this.to=void 0,this.containers=void 0,this.animation=void 0,this.trigger=void 0,this.cache=void 0,this.history=void 0,this.scroll=void 0;const{to:n,from:r=t.currentPageUrl,hash:o,el:i,event:s}=e;this.id=Math.random(),this.state=1,this.from={url:r},this.to={url:n,hash:o},this.containers=t.options.containers,this.animation={animate:!0,wait:!1,name:void 0,native:t.options.native,scope:t.options.animationScope,selector:t.options.animationSelector},this.trigger={el:i,event:s},this.cache={read:t.options.cache,write:t.options.cache},this.history={action:"push",popstate:!1,direction:void 0},this.scroll={reset:!0,target:void 0}}advance(t){this.state<t&&(this.state=t)}abort(){this.state=8}get done(){return this.state>=7}}function b(t){return new k(this,t)}const S="undefined"!=typeof Symbol?Symbol.iterator||(Symbol.iterator=Symbol("Symbol.iterator")):"@@iterator";function E(t,e,n){if(!t.s){if(n instanceof U){if(!n.s)return void(n.o=E.bind(null,t,e));1&e&&(e=n.s),n=n.v}if(n&&n.then)return void n.then(E.bind(null,t,e),E.bind(null,t,2));t.s=e,t.v=n;const r=t.o;r&&r(t)}}const U=/*#__PURE__*/function(){function t(){}return t.prototype.then=function(e,n){const r=new t,o=this.s;if(o){const t=1&o?e:n;if(t){try{E(r,1,t(this.v))}catch(t){E(r,2,t)}return r}return this}return this.o=function(t){try{const o=t.v;1&t.s?E(r,1,e?e(o):o):n?E(r,1,n(o)):E(r,2,o)}catch(t){E(r,2,t)}},r},t}();function C(t){return t instanceof U&&1&t.s}class ${constructor(t){this.swup=void 0,this.registry=new Map,this.hooks=["animation:out:start","animation:out:await","animation:out:end","animation:in:start","animation:in:await","animation:in:end","animation:skip","cache:clear","cache:set","content:replace","content:scroll","enable","disable","fetch:request","fetch:error","fetch:timeout","history:popstate","link:click","link:self","link:anchor","link:newtab","page:load","page:view","scroll:top","scroll:anchor","visit:start","visit:transition","visit:abort","visit:end"],this.swup=t,this.init()}init(){this.hooks.forEach(t=>this.create(t))}create(t){this.registry.has(t)||this.registry.set(t,new Map)}exists(t){return this.registry.has(t)}get(t){const e=this.registry.get(t);if(e)return e;console.error(`Unknown hook '${t}'`)}clear(){this.registry.forEach(t=>t.clear())}on(t,e,n={}){const r=this.get(t);if(!r)return console.warn(`Hook '${t}' not found.`),()=>{};const o={...n,id:r.size+1,hook:t,handler:e};return r.set(e,o),()=>this.off(t,e)}before(t,e,n={}){return this.on(t,e,{...n,before:!0})}replace(t,e,n={}){return this.on(t,e,{...n,replace:!0})}once(t,e,n={}){return this.on(t,e,{...n,once:!0})}off(t,e){const n=this.get(t);n&&e?n.delete(e)||console.warn(`Handler for hook '${t}' not found.`):n&&n.clear()}call(t,e,n,r){try{const o=this,[i,s,a]=o.parseCallArgs(t,e,n,r),{before:c,handler:l,after:h}=o.getHandlers(t,a);return Promise.resolve(o.run(c,i,s)).then(function(){return Promise.resolve(o.run(l,i,s)).then(function([e]){return Promise.resolve(o.run(h,i,s)).then(function(){return o.dispatchDomEvent(t,i,s),e})})})}catch(t){return Promise.reject(t)}}callSync(t,e,n,r){const[o,i,s]=this.parseCallArgs(t,e,n,r),{before:a,handler:c,after:l}=this.getHandlers(t,s);this.runSync(a,o,i);const[h]=this.runSync(c,o,i);return this.runSync(l,o,i),this.dispatchDomEvent(t,o,i),h}parseCallArgs(t,e,n,r){return e instanceof k||"object"!=typeof e&&"function"!=typeof n?[e,n,r]:[void 0,e,n]}run(t,e,n){try{const r=this,o=[],i=function(t,e,n){if("function"==typeof t[S]){var r,o,i,s=t[S]();if(function t(n){try{for(;!(r=s.next()).done;)if((n=e(r.value))&&n.then){if(!C(n))return void n.then(t,i||(i=E.bind(null,o=new U,2)));n=n.v}o?E(o,1,n):o=n}catch(t){E(o||(o=new U),2,t)}}(),s.return){var a=function(t){try{r.done||s.return()}catch(t){}return t};if(o&&o.then)return o.then(a,function(t){throw a(t)});a()}return o}if(!("length"in t))throw new TypeError("Object is not iterable");for(var c=[],l=0;l<t.length;l++)c.push(t[l]);return function(t,e,n){var r,o,i=-1;return function n(s){try{for(;++i<t.length;)if((s=e(i))&&s.then){if(!C(s))return void s.then(n,o||(o=E.bind(null,r=new U,2)));s=s.v}r?E(r,1,s):r=s}catch(t){E(r||(r=new U),2,t)}}(),r}(c,function(t){return e(c[t])})}(t,function({hook:t,handler:i,defaultHandler:s,once:a}){if(!e?.done)return a&&r.off(t,i),Promise.resolve(v(i,[e||r.swup.visit,n,s])).then(function(t){o.push(t)})});return Promise.resolve(i&&i.then?i.then(function(){return o}):o)}catch(t){return Promise.reject(t)}}runSync(t,e,n){const r=[];for(const{hook:o,handler:i,defaultHandler:s,once:a}of t){if(e?.done)continue;a&&this.off(o,i);const t=i(e||this.swup.visit,n,s);r.push(t),p(t)&&console.warn(`Promise returned from handler for synchronous hook '${o}'.Swup will not wait for it to resolve.`)}return r}getHandlers(t,e){const n=this.get(t);if(!n)return{found:!1,before:[],handler:[],after:[],replaced:!1};const r=Array.from(n.values()),o=this.sortRegistrations,i=r.filter(({before:t,replace:e})=>t&&!e).sort(o),s=r.filter(({replace:t})=>t).filter(t=>!0).sort(o),a=r.filter(({before:t,replace:e})=>!t&&!e).sort(o),c=s.length>0;let l=[];if(e&&(l=[{id:0,hook:t,handler:e}],c)){const n=s.length-1,r=t=>{const n=s[t-1];return n?(e,o)=>n.handler(e,o,r(t-1)):e};l=[{id:0,hook:t,handler:s[n].handler,defaultHandler:r(n)}]}return{found:!0,before:i,handler:l,after:a,replaced:c}}sortRegistrations(t,e){return(t.priority??0)-(e.priority??0)||t.id-e.id||0}dispatchDomEvent(t,e,n){if(e?.done)return;const r={hook:t,args:n,visit:e||this.swup.visit};document.dispatchEvent(new CustomEvent("swup:any",{detail:r,bubbles:!0})),document.dispatchEvent(new CustomEvent(`swup:${t}`,{detail:r,bubbles:!0}))}}const x=t=>{if(t&&"#"===t.charAt(0)&&(t=t.substring(1)),!t)return null;const e=decodeURIComponent(t);let n=document.getElementById(t)||document.getElementById(e)||d(`a[name='${w(t)}']`)||d(`a[name='${w(e)}']`);return n||"top"!==t||(n=document.body),n},A=function({elements:t,selector:e}){try{if(!1===e&&!t)return Promise.resolve();let n=[];if(t)n=Array.from(t);else if(e&&(n=m(e,document.body),!n.length))return console.warn(`[swup] No elements found matching animationSelector \`${e}\``),Promise.resolve();const r=n.map(t=>function(t){const{type:e,timeout:n,propCount:r}=function(t,e){const n=window.getComputedStyle(t),r=q(n,`${H}Delay`),o=q(n,`${H}Duration`),i=V(r,o),s=q(n,`${j}Delay`),a=q(n,`${j}Duration`),c=V(s,a);let l=null,h=0,u=0;return e===H?i>0&&(l=H,h=i,u=o.length):e===j?c>0&&(l=j,h=c,u=a.length):(h=Math.max(i,c),l=h>0?i>c?H:j:null,u=l?l===H?o.length:a.length:0),{type:l,timeout:h,propCount:u}}(t);return!(!e||!n)&&new Promise(o=>{const i=`${e}end`,s=performance.now();let a=0;const c=()=>{t.removeEventListener(i,l),o()},l=e=>{if(e.target===t){if(!function(t){return[`${H}end`,`${j}end`].includes(t.type)}(e))throw new Error("Not a transition or animation event.");(performance.now()-s)/1e3<e.elapsedTime||++a>=r&&c()}};setTimeout(()=>{a<r&&c()},n+1),t.addEventListener(i,l)})}(t));return r.filter(Boolean).length>0?Promise.resolve(Promise.all(r)).then(function(){}):(e&&console.warn(`[swup] No CSS animation duration defined on elements matching \`${e}\``),Promise.resolve())}catch(t){return Promise.reject(t)}},H="transition",j="animation";function q(t,e){return(t[e]||"").split(", ")}function V(t,e){for(;t.length<e.length;)t=t.concat(t);return Math.max(...e.map((e,n)=>y(e)+y(t[n])))}const I=function(t,e={}){try{let a;const c=this;function s(s){if(a)return s;c.navigating=!0,c.visit=t;const{el:l}=t.trigger;e.referrer=e.referrer||c.currentPageUrl,!1===e.animate&&(t.animation.animate=!1),t.animation.animate||c.classes.clear();const h=e.history||l?.getAttribute("data-swup-history")||void 0;h&&["push","replace"].includes(h)&&(t.history.action=h);const u=e.animation||l?.getAttribute("data-swup-animation")||void 0;return u&&(t.animation.name=u),"object"==typeof e.cache?(t.cache.read=e.cache.read??t.cache.read,t.cache.write=e.cache.write??t.cache.write):void 0!==e.cache&&(t.cache={read:!!e.cache,write:!!e.cache}),delete e.cache,function(s,a){try{var l=Promise.resolve(c.hooks.call("visit:start",t,void 0)).then(function(){function s(){if(!t.done)return Promise.resolve(c.hooks.call("visit:transition",t,void 0,function(){try{let n;function e(e){return n?e:(t.advance(4),Promise.resolve(c.animatePageOut(t)).then(function(){function e(){return Promise.resolve(c.animatePageIn(t)).then(function(){})}const n=function(){if(t.animation.native&&document.startViewTransition)return Promise.resolve(document.startViewTransition(function(){try{const e=c.renderPage;return Promise.resolve(a).then(function(n){return Promise.resolve(e.call(c,t,n))})}catch(t){return Promise.reject(t)}}).finished).then(function(){});{const e=c.renderPage;return Promise.resolve(a).then(function(n){return Promise.resolve(e.call(c,t,n)).then(function(){})})}}();return n&&n.then?n.then(e):e()}))}const r=function(){if(!t.animation.animate)return Promise.resolve(c.hooks.call("animation:skip",void 0)).then(function(){const e=c.renderPage;return Promise.resolve(a).then(function(r){return Promise.resolve(e.call(c,t,r)).then(function(){n=1})})})}();return Promise.resolve(r&&r.then?r.then(e):e(r))}catch(o){return Promise.reject(o)}})).then(function(){if(!t.done)return Promise.resolve(c.hooks.call("visit:end",t,void 0,()=>c.classes.clear())).then(function(){t.state=7,c.navigating=!1,c.onVisitEnd&&(c.onVisitEnd(),c.onVisitEnd=void 0)})})}t.state=3;const a=c.hooks.call("page:load",t,{options:e},function(t,e){try{function n(t){return e.page=t,e.cache=!!r,e.page}let r;return t.cache.read&&(r=c.cache.get(t.to.url)),Promise.resolve(r?n(r):Promise.resolve(c.fetchPage(t.to.url,e.options)).then(n))}catch(o){return Promise.reject(o)}});if(a.then(({html:e})=>{t.advance(5),t.to.html=e}),!t.history.popstate){const e=t.to.url+t.to.hash;"replace"===t.history.action||t.to.url===c.currentPageUrl?i(e):(c.currentHistoryIndex++,o(e,{index:c.currentHistoryIndex}))}c.currentPageUrl=r(),t.history.popstate&&c.classes.add("is-popstate"),t.animation.name&&c.classes.add(`to-${n(t.animation.name)}`);const l=function(){if(t.animation.wait)return Promise.resolve(a).then(function(){})}();return l&&l.then?l.then(s):s()})}catch(t){return a(t)}return l&&l.then?l.then(void 0,a):l}(0,function(e){e&&!e?.aborted?(t.state=9,console.error(e),c.options.skipPopStateHandling=()=>(window.location.href=t.to.url+t.to.hash,!0),window.history.go(-1)):t.state=8})}const l=function(){if(c.navigating)return function(){if(!(c.visit.state>=6))return Promise.resolve(c.hooks.call("visit:abort",c.visit,void 0)).then(function(){c.visit.state=8});t.state=2,c.onVisitEnd=()=>c.performNavigation(t,e),a=1}()}();return Promise.resolve(l&&l.then?l.then(s):s(l))}catch(h){return Promise.reject(h)}};function L(t,e={},n={}){if("string"!=typeof t)throw new Error("swup.navigate() requires a URL parameter");if(this.shouldIgnoreVisit(t,{el:n.el,event:n.event}))return void(window.location.href=t);const{url:r,hash:o}=a.fromUrl(t),i=this.createVisit({...n,to:r,hash:o});this.performNavigation(i,e)}const R=function(t){try{const e=this;return Promise.resolve(e.hooks.call("animation:out:start",t,void 0,()=>{e.classes.add("is-changing","is-animating","is-leaving")})).then(function(){return Promise.resolve(e.hooks.call("animation:out:await",t,{skip:!1},(t,{skip:n})=>{if(!n)return e.awaitAnimations({selector:t.animation.selector})})).then(function(){return Promise.resolve(e.hooks.call("animation:out:end",t,void 0)).then(function(){})})})}catch(t){return Promise.reject(t)}},T=function({html:t},{containers:e}=this.options){const n=(new DOMParser).parseFromString(t,"text/html"),r=n.querySelector("title")?.innerText||"";document.title=r;const o=m('[data-swup-persist]:not([data-swup-persist=""])'),i=e.map(t=>{const e=document.querySelector(t),r=n.querySelector(t);return e&&r?(e.replaceWith(r),!0):(e||console.warn(`[swup] Container missing in current document: ${t}`),r||console.warn(`[swup] Container missing in incoming document: ${t}`),!1)}).filter(Boolean);return o.forEach(t=>{const e=t.getAttribute("data-swup-persist"),n=d(`[data-swup-persist="${e}"]`);n&&n!==t&&n.replaceWith(t)}),i.length===e.length},N=function(t){const e={behavior:"auto"},{target:n,reset:r}=t.scroll,o=n??t.to.hash;let i=!1;return o&&(i=this.hooks.callSync("scroll:anchor",t,{hash:o,options:e},(t,{hash:e,options:n})=>{const r=this.getAnchorElement(e);return r&&r.scrollIntoView(n),!!r})),r&&!i&&(i=this.hooks.callSync("scroll:top",t,{options:e},(t,{options:e})=>(window.scrollTo({top:0,left:0,...e}),!0))),i},D=function(t){try{const e=this;if(t.done)return Promise.resolve();const n=e.hooks.call("animation:in:await",t,{skip:!1},(t,{skip:n})=>{if(!n)return e.awaitAnimations({selector:t.animation.selector})});return Promise.resolve(f()).then(function(){return Promise.resolve(e.hooks.call("animation:in:start",t,void 0,()=>{e.classes.remove("is-animating")})).then(function(){return Promise.resolve(n).then(function(){return Promise.resolve(e.hooks.call("animation:in:end",t,void 0)).then(function(){})})})})}catch(t){return Promise.reject(t)}},M=function(t,e){try{const o=this;if(t.done)return Promise.resolve();t.advance(6);const{url:s}=e;return o.classes.remove("is-leaving"),o.isSameResolvedUrl(r(),s)||(i(s),o.currentPageUrl=r(),t.to.url=o.currentPageUrl),t.animation.animate&&o.classes.add("is-rendering"),Promise.resolve(o.hooks.call("content:replace",t,{page:e},(t,{page:e})=>{if(!o.replaceContent(e,{containers:t.containers}))throw new Error("[swup] Container mismatch, aborting");t.animation.animate&&(o.classes.add("is-changing","is-animating","is-rendering"),t.animation.name&&o.classes.add(`to-${n(t.animation.name)}`))})).then(function(){return Promise.resolve(o.hooks.call("content:scroll",t,void 0,()=>o.scrollToContent(t))).then(function(){return Promise.resolve(o.hooks.call("page:view",t,{url:o.currentPageUrl,title:document.title})).then(function(){})})})}catch(t){return Promise.reject(t)}},O=function(t){var e;if(e=t,Boolean(e?.isSwupPlugin)){if(t.swup=this,!t._checkRequirements||t._checkRequirements())return t._beforeMount&&t._beforeMount(),t.mount(),this.plugins.push(t),this.plugins}else console.error("Not a swup plugin instance",t)};function W(t){const e=this.findPlugin(t);if(e)return e.unmount(),e._afterUnmount&&e._afterUnmount(),this.plugins=this.plugins.filter(t=>t!==e),this.plugins;console.error("No such plugin",e)}function B(t){return this.plugins.find(e=>e===t||e.name===t||e.name===`Swup${String(t)}`)}function _(t){if("function"!=typeof this.options.resolveUrl)return console.warn("[swup] options.resolveUrl expects a callback function."),t;const e=this.options.resolveUrl(t);return e&&"string"==typeof e?e.startsWith("//")||e.startsWith("http")?(console.warn("[swup] options.resolveUrl needs to return a relative url"),t):e:(console.warn("[swup] options.resolveUrl needs to return a url"),t)}function F(t,e){return this.resolveUrl(t)===this.resolveUrl(e)}const K={animateHistoryBrowsing:!1,animationSelector:'[class*="transition-"]',animationScope:"html",cache:!0,containers:["#swup"],ignoreVisit:(t,{el:e}={})=>!!e?.closest("[data-no-swup]"),linkSelector:"a[href]",linkToSelf:"scroll",native:!1,plugins:[],resolveUrl:t=>t,requestHeaders:{"X-Requested-With":"swup",Accept:"text/html, application/xhtml+xml"},skipPopStateHandling:t=>"swup"!==t.state?.source,timeout:0};class z{constructor(t={}){this.version="4.5.0",this.options=void 0,this.defaults=K,this.plugins=[],this.visit=void 0,this.cache=void 0,this.hooks=void 0,this.classes=void 0,this.currentPageUrl=r(),this.currentHistoryIndex=void 0,this.clickDelegate=void 0,this.navigating=!1,this.onVisitEnd=void 0,this.use=O,this.unuse=W,this.findPlugin=B,this.log=()=>{},this.navigate=L,this.performNavigation=I,this.createVisit=b,this.delegateEvent=s,this.fetchPage=l,this.awaitAnimations=A,this.renderPage=M,this.replaceContent=T,this.animatePageIn=D,this.animatePageOut=R,this.scrollToContent=N,this.getAnchorElement=x,this.getCurrentUrl=r,this.resolveUrl=_,this.isSameResolvedUrl=F,this.options={...this.defaults,...t},this.handleLinkClick=this.handleLinkClick.bind(this),this.handlePopState=this.handlePopState.bind(this),this.cache=new u(this),this.classes=new P(this),this.hooks=new $(this),this.visit=this.createVisit({to:""}),this.currentHistoryIndex=history.state?.index??1,this.checkRequirements()&&this.enable()}checkRequirements(){return"undefined"!=typeof Promise||(console.warn("Promise is not supported"),!1)}enable(){try{const t=this,{linkSelector:e}=t.options;return t.clickDelegate=t.delegateEvent(e,"click",t.handleLinkClick),window.addEventListener("popstate",t.handlePopState),t.options.animateHistoryBrowsing&&(window.history.scrollRestoration="manual"),t.options.native=t.options.native&&!!document.startViewTransition,t.options.plugins.forEach(e=>t.use(e)),"swup"!==history.state?.source&&i(null,{index:t.currentHistoryIndex}),Promise.resolve(f()).then(function(){return Promise.resolve(t.hooks.call("enable",void 0,void 0,()=>{const e=document.documentElement;e.classList.add("swup-enabled"),e.classList.toggle("swup-native",t.options.native)})).then(function(){})})}catch(t){return Promise.reject(t)}}destroy(){try{const t=this;return t.clickDelegate.destroy(),window.removeEventListener("popstate",t.handlePopState),t.cache.clear(),t.options.plugins.forEach(e=>t.unuse(e)),Promise.resolve(t.hooks.call("disable",void 0,void 0,()=>{const t=document.documentElement;t.classList.remove("swup-enabled"),t.classList.remove("swup-native")})).then(function(){t.hooks.clear()})}catch(t){return Promise.reject(t)}}shouldIgnoreVisit(t,{el:e,event:n}={}){const{origin:r,url:o,hash:i}=a.fromUrl(t);return r!==window.location.origin||!(!e||!this.triggerWillOpenNewWindow(e))||!!this.options.ignoreVisit(o+i,{el:e,event:n})}handleLinkClick(t){const e=t.delegateTarget,{href:n,url:r,hash:o}=a.fromElement(e);if(this.shouldIgnoreVisit(n,{el:e,event:t}))return;if(this.navigating&&r===this.visit.to.url)return void t.preventDefault();const s=this.createVisit({to:r,hash:o,el:e,event:t});t.metaKey||t.ctrlKey||t.shiftKey||t.altKey?this.hooks.callSync("link:newtab",s,{href:n}):0===t.button&&this.hooks.callSync("link:click",s,{el:e,event:t},()=>{const e=s.from.url??"";t.preventDefault(),r&&r!==e?this.isSameResolvedUrl(r,e)||this.performNavigation(s):o?this.hooks.callSync("link:anchor",s,{hash:o},()=>{i(r+o),this.scrollToContent(s)}):this.hooks.callSync("link:self",s,void 0,()=>{"navigate"===this.options.linkToSelf?this.performNavigation(s):(i(r),this.scrollToContent(s))})})}handlePopState(t){const e=t.state?.url??location.href;if(this.options.skipPopStateHandling(t))return;if(this.isSameResolvedUrl(r(),this.currentPageUrl))return;const{url:n,hash:o}=a.fromUrl(e),i=this.createVisit({to:n,hash:o,event:t});i.history.popstate=!0;const s=t.state?.index??0;s&&s!==this.currentHistoryIndex&&(i.history.direction=s-this.currentHistoryIndex>0?"forwards":"backwards",this.currentHistoryIndex=s),i.animation.animate=!1,i.scroll.reset=!1,i.scroll.target=!1,this.options.animateHistoryBrowsing&&(i.animation.animate=!0,i.scroll.reset=!0),this.hooks.callSync("history:popstate",i,{event:t},()=>{this.performNavigation(i)})}triggerWillOpenNewWindow(t){return!!t.matches('[download], [target="_blank"]')}}export{a as Location,n as classify,o as createHistoryRecord,z as default,s as delegateEvent,w as escapeCssIdentifier,g as forceReflow,r as getCurrentUrl,p as isPromise,c as matchPath,f as nextTick,d as query,m as queryAll,v as runAsPromise,y as toMs,i as updateHistoryRecord}; | ||
//# sourceMappingURL=Swup.module.js.map |
@@ -1,2 +0,2 @@ | ||
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t||self).Swup=e()}(this,function(){const t=new WeakMap;function e(e,n,o,r){if(!e&&!t.has(n))return!1;const i=t.get(n)??new WeakMap;t.set(n,i);const s=i.get(o)??new Set;i.set(o,s);const a=s.has(r);return e?s.add(r):s.delete(r),a&&e}const n=(t,e)=>String(t).toLowerCase().replace(/[\s/_.]+/g,"-").replace(/[^\w-]+/g,"").replace(/--+/g,"-").replace(/^-+|-+$/g,"")||e||"",o=function(t){let{hash:e}=void 0===t?{}:t;return location.pathname+location.search+(e?location.hash:"")},r=function(t,e){void 0===e&&(e={});const n={url:t=t||o({hash:!0}),random:Math.random(),source:"swup",...e};history.pushState(n,"",t)},i=function(t,e){void 0===t&&(t=null),void 0===e&&(e={}),t=t||o({hash:!0});const n={...history.state||{},url:t,random:Math.random(),source:"swup",...e};history.replaceState(n,"",t)},s=(t,n,o,r)=>{const i=new AbortController;return function(t,n,o,r={}){const{signal:i,base:s=document}=r;if(i?.aborted)return;const{once:a,...c}=r,l=s instanceof Document?s.documentElement:s,h=Boolean("object"==typeof r?r.capture:r),u=r=>{const i=function(t,e){let n=t.target;if(n instanceof Text&&(n=n.parentElement),n instanceof Element&&t.currentTarget instanceof Element){const o=n.closest(e);if(o&&t.currentTarget.contains(o))return o}}(r,t);if(i){const t=Object.assign(r,{delegateTarget:i});o.call(l,t),a&&(l.removeEventListener(n,u,c),e(!1,l,o,d))}},d=JSON.stringify({selector:t,type:n,capture:h});e(!0,l,o,d)||l.addEventListener(n,u,c),i?.addEventListener("abort",()=>{e(!1,l,o,d)})}(t,n,o,r={...r,signal:i.signal}),{destroy:()=>i.abort()}};class a extends URL{constructor(t,e){void 0===e&&(e=document.baseURI),super(t.toString(),e),Object.setPrototypeOf(this,a.prototype)}get url(){return this.pathname+this.search}static fromElement(t){const e=t.getAttribute("href")||t.getAttribute("xlink:href")||"";return new a(e)}static fromUrl(t){return new a(t)}}const c=function(t,e){void 0===e&&(e={});try{const o=this;function n(n){const{status:r,url:i}=h;return Promise.resolve(h.text()).then(function(n){if(500===r)throw o.hooks.call("fetch:error",{status:r,response:h,url:i}),new l(`Server error: ${i}`,{status:r,url:i});if(!n)throw new l(`Empty response: ${i}`,{status:r,url:i});const{url:s}=a.fromUrl(i),c={url:s,html:n};return!o.visit.cache.write||e.method&&"GET"!==e.method||t!==s||o.cache.set(c.url,c),c})}t=a.fromUrl(t).url;const r={...o.options.requestHeaders,...e.headers},i=e.timeout??o.options.timeout,s=new AbortController,{signal:c}=s;e={...e,headers:r,signal:c};let h,u=!1,d=null;i&&i>0&&(d=setTimeout(()=>{u=!0,s.abort("timeout")},i));const m=function(n,r){try{var i=Promise.resolve(o.hooks.call("fetch:request",{url:t,options:e},(t,e)=>{let{url:n,options:o}=e;return fetch(n,o)})).then(function(t){h=t,d&&clearTimeout(d)})}catch(t){return r(t)}return i&&i.then?i.then(void 0,r):i}(0,function(e){if(u)throw o.hooks.call("fetch:timeout",{url:t}),new l(`Request timed out: ${t}`,{url:t,timedOut:u});if("AbortError"===e?.name||c.aborted)throw new l(`Request aborted: ${t}`,{url:t,aborted:!0});throw e});return Promise.resolve(m&&m.then?m.then(n):n())}catch(f){return Promise.reject(f)}};class l extends Error{constructor(t,e){super(t),this.url=void 0,this.status=void 0,this.aborted=void 0,this.timedOut=void 0,this.name="FetchError",this.url=e.url,this.status=e.status,this.aborted=e.aborted||!1,this.timedOut=e.timedOut||!1}}class h{constructor(t){this.swup=void 0,this.pages=new Map,this.swup=t}get size(){return this.pages.size}get all(){const t=new Map;return this.pages.forEach((e,n)=>{t.set(n,{...e})}),t}has(t){return this.pages.has(this.resolve(t))}get(t){const e=this.pages.get(this.resolve(t));return e?{...e}:e}set(t,e){t=this.resolve(t),e={...e,url:t},this.pages.set(t,e),this.swup.hooks.callSync("cache:set",{page:e})}update(t,e){t=this.resolve(t);const n={...this.get(t),...e,url:t};this.pages.set(t,n)}delete(t){this.pages.delete(this.resolve(t))}clear(){this.pages.clear(),this.swup.hooks.callSync("cache:clear",void 0)}prune(t){this.pages.forEach((e,n)=>{t(n,e)&&this.delete(n)})}resolve(t){const{url:e}=a.fromUrl(t);return this.swup.resolveUrl(e)}}const u=function(t,e){return void 0===e&&(e=document),e.querySelector(t)},d=function(t,e){return void 0===e&&(e=document),Array.from(e.querySelectorAll(t))},m=()=>new Promise(t=>{requestAnimationFrame(()=>{requestAnimationFrame(()=>{t()})})});function f(t){return!!t&&("object"==typeof t||"function"==typeof t)&&"function"==typeof t.then}const p=t=>window.CSS&&window.CSS.escape?CSS.escape(t):t,v=t=>1e3*Number(t.slice(0,-1).replace(",","."));class g{constructor(t){this.swup=void 0,this.swupClasses=["to-","is-changing","is-rendering","is-popstate","is-animating"],this.swup=t}get selectors(){const{scope:t}=this.swup.visit.animation;return"containers"===t?this.swup.visit.containers:"html"===t?["html"]:Array.isArray(t)?t:[]}get selector(){return this.selectors.join(",")}get targets(){return this.selector.trim()?d(this.selector):[]}add(){this.targets.forEach(t=>t.classList.add(...[].slice.call(arguments)))}remove(){this.targets.forEach(t=>t.classList.remove(...[].slice.call(arguments)))}clear(){this.targets.forEach(t=>{const e=t.className.split(" ").filter(t=>this.isSwupClass(t));t.classList.remove(...e)})}isSwupClass(t){return this.swupClasses.some(e=>t.startsWith(e))}}function w(t){let{to:e,from:n=this.currentPageUrl,hash:o,el:r,event:i}=t;return{id:Math.random(),from:{url:n},to:{url:e,hash:o},containers:this.options.containers,animation:{animate:!0,wait:!1,name:void 0,scope:this.options.animationScope,selector:this.options.animationSelector},trigger:{el:r,event:i},cache:{read:this.options.cache,write:this.options.cache},history:{action:"push",popstate:!1,direction:void 0},scroll:{reset:!0,target:void 0}}}const y="undefined"!=typeof Symbol?Symbol.iterator||(Symbol.iterator=Symbol("Symbol.iterator")):"@@iterator";function P(t,e,n){if(!t.s){if(n instanceof k){if(!n.s)return void(n.o=P.bind(null,t,e));1&e&&(e=n.s),n=n.v}if(n&&n.then)return void n.then(P.bind(null,t,e),P.bind(null,t,2));t.s=e,t.v=n;const o=t.o;o&&o(t)}}const k=/*#__PURE__*/function(){function t(){}return t.prototype.then=function(e,n){const o=new t,r=this.s;if(r){const t=1&r?e:n;if(t){try{P(o,1,t(this.v))}catch(t){P(o,2,t)}return o}return this}return this.o=function(t){try{const r=t.v;1&t.s?P(o,1,e?e(r):r):n?P(o,1,n(r)):P(o,2,r)}catch(t){P(o,2,t)}},o},t}();function b(t){return t instanceof k&&1&t.s}class S{constructor(t){this.swup=void 0,this.registry=new Map,this.hooks=["animation:out:start","animation:out:await","animation:out:end","animation:in:start","animation:in:await","animation:in:end","animation:skip","cache:clear","cache:set","content:replace","content:scroll","enable","disable","fetch:request","fetch:error","fetch:timeout","history:popstate","link:click","link:self","link:anchor","link:newtab","page:load","page:view","scroll:top","scroll:anchor","visit:start","visit:transition","visit:end"],this.swup=t,this.init()}init(){this.hooks.forEach(t=>this.create(t))}create(t){this.registry.has(t)||this.registry.set(t,new Map)}exists(t){return this.registry.has(t)}get(t){const e=this.registry.get(t);if(e)return e;console.error(`Unknown hook '${t}'`)}clear(){this.registry.forEach(t=>t.clear())}on(t,e,n){void 0===n&&(n={});const o=this.get(t);if(!o)return console.warn(`Hook '${t}' not found.`),()=>{};const r=o.size+1,i={...n,id:r,hook:t,handler:e};return o.set(e,i),()=>this.off(t,e)}before(t,e,n){return void 0===n&&(n={}),this.on(t,e,{...n,before:!0})}replace(t,e,n){return void 0===n&&(n={}),this.on(t,e,{...n,replace:!0})}once(t,e,n){return void 0===n&&(n={}),this.on(t,e,{...n,once:!0})}off(t,e){const n=this.get(t);n&&e?n.delete(e)||console.warn(`Handler for hook '${t}' not found.`):n&&n.clear()}call(t,e,n){try{const o=this,{before:r,handler:i,after:s}=o.getHandlers(t,n);return Promise.resolve(o.run(r,e)).then(function(){return Promise.resolve(o.run(i,e)).then(function(n){let[r]=n;return Promise.resolve(o.run(s,e)).then(function(){return o.dispatchDomEvent(t,e),r})})})}catch(t){return Promise.reject(t)}}callSync(t,e,n){const{before:o,handler:r,after:i}=this.getHandlers(t,n);this.runSync(o,e);const[s]=this.runSync(r,e);return this.runSync(i,e),this.dispatchDomEvent(t,e),s}run(t,e){try{const n=this,o=[],r=function(t,e,n){if("function"==typeof t[y]){var o,r,i,s=t[y]();if(function t(n){try{for(;!(o=s.next()).done;)if((n=e(o.value))&&n.then){if(!b(n))return void n.then(t,i||(i=P.bind(null,r=new k,2)));n=n.v}r?P(r,1,n):r=n}catch(t){P(r||(r=new k),2,t)}}(),s.return){var a=function(t){try{o.done||s.return()}catch(t){}return t};if(r&&r.then)return r.then(a,function(t){throw a(t)});a()}return r}if(!("length"in t))throw new TypeError("Object is not iterable");for(var c=[],l=0;l<t.length;l++)c.push(t[l]);return function(t,e,n){var o,r,i=-1;return function n(s){try{for(;++i<t.length;)if((s=e(i))&&s.then){if(!b(s))return void s.then(n,r||(r=P.bind(null,o=new k,2)));s=s.v}o?P(o,1,s):o=s}catch(t){P(o||(o=new k),2,t)}}(),o}(c,function(t){return e(c[t])})}(t,function(t){let{hook:r,handler:i,defaultHandler:s,once:a}=t;return Promise.resolve(function(t,e){return void 0===e&&(e=[]),new Promise((n,o)=>{const r=t(...e);f(r)?r.then(n,o):n(r)})}(i,[n.swup.visit,e,s])).then(function(t){o.push(t),a&&n.off(r,i)})});return Promise.resolve(r&&r.then?r.then(function(){return o}):o)}catch(t){return Promise.reject(t)}}runSync(t,e){const n=[];for(const{hook:o,handler:r,defaultHandler:i,once:s}of t){const t=r(this.swup.visit,e,i);n.push(t),f(t)&&console.warn(`Promise returned from handler for synchronous hook '${o}'.Swup will not wait for it to resolve.`),s&&this.off(o,r)}return n}getHandlers(t,e){const n=this.get(t);if(!n)return{found:!1,before:[],handler:[],after:[],replaced:!1};const o=Array.from(n.values()),r=this.sortRegistrations,i=o.filter(t=>{let{before:e,replace:n}=t;return e&&!n}).sort(r),s=o.filter(t=>{let{replace:e}=t;return e}).filter(t=>!0).sort(r),a=o.filter(t=>{let{before:e,replace:n}=t;return!e&&!n}).sort(r),c=s.length>0;let l=[];if(e&&(l=[{id:0,hook:t,handler:e}],c)){const n=s.length-1,o=t=>{const n=s[t-1];return n?(e,r)=>n.handler(e,r,o(t-1)):e};l=[{id:0,hook:t,handler:s[n].handler,defaultHandler:o(n)}]}return{found:!0,before:i,handler:l,after:a,replaced:c}}sortRegistrations(t,e){return(t.priority??0)-(e.priority??0)||t.id-e.id||0}dispatchDomEvent(t,e){const n={hook:t,args:e,visit:this.swup.visit};document.dispatchEvent(new CustomEvent("swup:any",{detail:n,bubbles:!0})),document.dispatchEvent(new CustomEvent(`swup:${t}`,{detail:n,bubbles:!0}))}}const E=t=>{if(t&&"#"===t.charAt(0)&&(t=t.substring(1)),!t)return null;const e=decodeURIComponent(t);let n=document.getElementById(t)||document.getElementById(e)||u(`a[name='${p(t)}']`)||u(`a[name='${p(e)}']`);return n||"top"!==t||(n=document.body),n},U=function(t){let{elements:e,selector:n}=t;try{if(!1===n&&!e)return Promise.resolve();let t=[];if(e)t=Array.from(e);else if(n&&(t=d(n,document.body),!t.length))return console.warn(`[swup] No elements found matching animationSelector \`${n}\``),Promise.resolve();const o=t.map(t=>function(t){const{type:e,timeout:n,propCount:o}=function(t,e){const n=window.getComputedStyle(t),o=$(n,`${C}Delay`),r=$(n,`${C}Duration`),i=H(o,r),s=$(n,`${x}Delay`),a=$(n,`${x}Duration`),c=H(s,a);let l=null,h=0,u=0;return e===C?i>0&&(l=C,h=i,u=r.length):e===x?c>0&&(l=x,h=c,u=a.length):(h=Math.max(i,c),l=h>0?i>c?C:x:null,u=l?l===C?r.length:a.length:0),{type:l,timeout:h,propCount:u}}(t);return!(!e||!n)&&new Promise(r=>{const i=`${e}end`,s=performance.now();let a=0;const c=()=>{t.removeEventListener(i,l),r()},l=e=>{if(e.target===t){if(!function(t){return[`${C}end`,`${x}end`].includes(t.type)}(e))throw new Error("Not a transition or animation event.");(performance.now()-s)/1e3<e.elapsedTime||++a>=o&&c()}};setTimeout(()=>{a<o&&c()},n+1),t.addEventListener(i,l)})}(t));return o.filter(Boolean).length>0?Promise.resolve(Promise.all(o)).then(function(){}):(n&&console.warn(`[swup] No CSS animation duration defined on elements matching \`${n}\``),Promise.resolve())}catch(t){return Promise.reject(t)}},C="transition",x="animation";function $(t,e){return(t[e]||"").split(", ")}function H(t,e){for(;t.length<e.length;)t=t.concat(t);return Math.max(...e.map((e,n)=>v(e)+v(t[n])))}const A=function(t){void 0===t&&(t={});try{const e=this;e.navigating=!0;const n=e.visit,{el:s}=n.trigger;t.referrer=t.referrer||e.currentPageUrl,!1===t.animate&&(n.animation.animate=!1),n.animation.animate||e.classes.clear();const a=t.history||s?.getAttribute("data-swup-history")||void 0;a&&["push","replace"].includes(a)&&(n.history.action=a);const c=t.animation||s?.getAttribute("data-swup-animation")||void 0;return c&&(n.animation.name=c),"object"==typeof t.cache?(n.cache.read=t.cache.read??n.cache.read,n.cache.write=t.cache.write??n.cache.write):void 0!==t.cache&&(n.cache={read:!!t.cache,write:!!t.cache}),delete t.cache,Promise.resolve(function(s,a){try{var c=Promise.resolve(e.hooks.call("visit:start",void 0)).then(function(){function s(){return Promise.resolve(e.hooks.call("visit:transition",void 0,function(t){try{const n=e.animatePageOut();return Promise.resolve(Promise.all([a,n])).then(function(n){let[o]=n;return t.id===e.visit.id&&Promise.resolve(e.renderPage(o)).then(function(){return Promise.resolve(e.animatePageIn()).then(function(){return!0})})})}catch(t){return Promise.reject(t)}})).then(function(){return Promise.resolve(e.hooks.call("visit:end",void 0,()=>e.classes.clear())).then(function(){e.navigating=!1})})}const a=e.hooks.call("page:load",{options:t},function(t,n){try{function o(t){return n.page=t,n.cache=!!r,n.page}let r;return t.cache.read&&(r=e.cache.get(t.to.url)),Promise.resolve(r?o(r):Promise.resolve(e.fetchPage(t.to.url,n.options)).then(o))}catch(i){return Promise.reject(i)}});if(!n.history.popstate){const t=n.to.url+n.to.hash;"replace"===n.history.action||n.to.url===e.currentPageUrl?i(t):(e.currentHistoryIndex++,r(t,{index:e.currentHistoryIndex}))}e.currentPageUrl=o();const c=function(){if(n.animation.wait)return Promise.resolve(a).then(function(t){let{html:e}=t;n.to.html=e})}();return c&&c.then?c.then(s):s()})}catch(t){return a(t)}return c&&c.then?c.then(void 0,a):c}(0,function(t){t&&!t?.aborted&&(console.error(t),e.options.skipPopStateHandling=()=>(window.location.href=n.to.url+n.to.hash,!0),window.history.go(-1))}))}catch(t){return Promise.reject(t)}};function j(t,e,n){if(void 0===e&&(e={}),void 0===n&&(n={}),"string"!=typeof t)throw new Error("swup.navigate() requires a URL parameter");if(this.shouldIgnoreVisit(t,{el:n.el,event:n.event}))return void(window.location.href=t);const{url:o,hash:r}=a.fromUrl(t);this.visit=this.createVisit({...n,to:o,hash:r}),this.performNavigation(e)}const T=function(){try{let e;const o=this;function t(t){return e?t:Promise.resolve(o.hooks.call("animation:out:start",void 0,t=>{o.classes.add("is-changing","is-leaving","is-animating"),t.history.popstate&&o.classes.add("is-popstate"),t.animation.name&&o.classes.add(`to-${n(t.animation.name)}`)})).then(function(){return Promise.resolve(o.hooks.call("animation:out:await",{skip:!1},function(t,e){let{skip:n}=e;try{return n?Promise.resolve():Promise.resolve(o.awaitAnimations({selector:t.animation.selector})).then(function(){})}catch(t){return Promise.reject(t)}})).then(function(){return Promise.resolve(o.hooks.call("animation:out:end",void 0)).then(function(){})})})}const r=function(){if(!o.visit.animation.animate)return Promise.resolve(o.hooks.call("animation:skip",void 0)).then(function(){e=1})}();return Promise.resolve(r&&r.then?r.then(t):t(r))}catch(i){return Promise.reject(i)}},q=function(t,e){let{html:n}=t,{containers:o}=void 0===e?this.options:e;const r=(new DOMParser).parseFromString(n,"text/html"),i=r.querySelector("title")?.innerText||"";document.title=i;const s=d('[data-swup-persist]:not([data-swup-persist=""])'),a=o.map(t=>{const e=document.querySelector(t),n=r.querySelector(t);return e&&n?(e.replaceWith(n),!0):(e||console.warn(`[swup] Container missing in current document: ${t}`),n||console.warn(`[swup] Container missing in incoming document: ${t}`),!1)}).filter(Boolean);return s.forEach(t=>{const e=t.getAttribute("data-swup-persist"),n=u(`[data-swup-persist="${e}"]`);n&&n!==t&&n.replaceWith(t)}),a.length===o.length},L=function(){const t={behavior:"auto"},{target:e,reset:n}=this.visit.scroll,o=e??this.visit.to.hash;let r=!1;return o&&(r=this.hooks.callSync("scroll:anchor",{hash:o,options:t},(t,e)=>{let{hash:n,options:o}=e;const r=this.getAnchorElement(n);return r&&r.scrollIntoView(o),!!r})),n&&!r&&(r=this.hooks.callSync("scroll:top",{options:t},(t,e)=>{let{options:n}=e;return window.scrollTo({top:0,left:0,...n}),!0})),r},I=function(){try{const t=this;if(!t.visit.animation.animate)return Promise.resolve();const e=t.hooks.call("animation:in:await",{skip:!1},function(e,n){let{skip:o}=n;try{return o?Promise.resolve():Promise.resolve(t.awaitAnimations({selector:e.animation.selector})).then(function(){})}catch(t){return Promise.reject(t)}});return Promise.resolve(m()).then(function(){return Promise.resolve(t.hooks.call("animation:in:start",void 0,()=>{t.classes.remove("is-animating")})).then(function(){return Promise.resolve(e).then(function(){return Promise.resolve(t.hooks.call("animation:in:end",void 0)).then(function(){})})})})}catch(t){return Promise.reject(t)}},R=function(t){try{const e=this,{url:r,html:s}=t;return e.classes.remove("is-leaving"),e.isSameResolvedUrl(o(),r)||(i(r),e.currentPageUrl=o(),e.visit.to.url=e.currentPageUrl),e.visit.animation.animate&&e.classes.add("is-rendering"),e.visit.to.html=s,Promise.resolve(e.hooks.call("content:replace",{page:t},(t,o)=>{let{page:r}=o;if(!e.replaceContent(r,{containers:t.containers}))throw new Error("[swup] Container mismatch, aborting");t.animation.animate&&(e.classes.add("is-animating","is-changing","is-rendering"),t.animation.name&&e.classes.add(`to-${n(t.animation.name)}`))})).then(function(){return Promise.resolve(e.hooks.call("content:scroll",void 0,()=>e.scrollToContent())).then(function(){return Promise.resolve(e.hooks.call("page:view",{url:e.currentPageUrl,title:document.title})).then(function(){})})})}catch(t){return Promise.reject(t)}},N=function(t){var e;if(e=t,Boolean(e?.isSwupPlugin)){if(t.swup=this,!t._checkRequirements||t._checkRequirements())return t._beforeMount&&t._beforeMount(),t.mount(),this.plugins.push(t),this.plugins}else console.error("Not a swup plugin instance",t)};function D(t){const e=this.findPlugin(t);if(e)return e.unmount(),e._afterUnmount&&e._afterUnmount(),this.plugins=this.plugins.filter(t=>t!==e),this.plugins;console.error("No such plugin",e)}function M(t){return this.plugins.find(e=>e===t||e.name===t||e.name===`Swup${String(t)}`)}function O(t){if("function"!=typeof this.options.resolveUrl)return console.warn("[swup] options.resolveUrl expects a callback function."),t;const e=this.options.resolveUrl(t);return e&&"string"==typeof e?e.startsWith("//")||e.startsWith("http")?(console.warn("[swup] options.resolveUrl needs to return a relative url"),t):e:(console.warn("[swup] options.resolveUrl needs to return a url"),t)}function W(t,e){return this.resolveUrl(t)===this.resolveUrl(e)}const V={animateHistoryBrowsing:!1,animationSelector:'[class*="transition-"]',animationScope:"html",cache:!0,containers:["#swup"],ignoreVisit:function(t,e){let{el:n}=void 0===e?{}:e;return!!n?.closest("[data-no-swup]")},linkSelector:"a[href]",linkToSelf:"scroll",plugins:[],resolveUrl:t=>t,requestHeaders:{"X-Requested-With":"swup",Accept:"text/html, application/xhtml+xml"},skipPopStateHandling:t=>"swup"!==t.state?.source,timeout:0};return class{constructor(t){void 0===t&&(t={}),this.version="4.4.4",this.options=void 0,this.defaults=V,this.plugins=[],this.visit=void 0,this.cache=void 0,this.hooks=void 0,this.classes=void 0,this.currentPageUrl=o(),this.currentHistoryIndex=void 0,this.clickDelegate=void 0,this.navigating=!1,this.use=N,this.unuse=D,this.findPlugin=M,this.log=()=>{},this.navigate=j,this.performNavigation=A,this.createVisit=w,this.delegateEvent=s,this.fetchPage=c,this.awaitAnimations=U,this.renderPage=R,this.replaceContent=q,this.animatePageIn=I,this.animatePageOut=T,this.scrollToContent=L,this.getAnchorElement=E,this.getCurrentUrl=o,this.resolveUrl=O,this.isSameResolvedUrl=W,this.options={...this.defaults,...t},this.handleLinkClick=this.handleLinkClick.bind(this),this.handlePopState=this.handlePopState.bind(this),this.cache=new h(this),this.classes=new g(this),this.hooks=new S(this),this.visit=this.createVisit({to:""}),this.currentHistoryIndex=history.state?.index??1,this.checkRequirements()&&this.enable()}checkRequirements(){return"undefined"!=typeof Promise||(console.warn("Promise is not supported"),!1)}enable(){try{const t=this,{linkSelector:e}=t.options;return t.clickDelegate=t.delegateEvent(e,"click",t.handleLinkClick),window.addEventListener("popstate",t.handlePopState),t.options.animateHistoryBrowsing&&(window.history.scrollRestoration="manual"),t.options.plugins.forEach(e=>t.use(e)),"swup"!==history.state?.source&&i(null,{index:t.currentHistoryIndex}),Promise.resolve(m()).then(function(){return Promise.resolve(t.hooks.call("enable",void 0,()=>{document.documentElement.classList.add("swup-enabled")})).then(function(){})})}catch(t){return Promise.reject(t)}}destroy(){try{const t=this;return t.clickDelegate.destroy(),window.removeEventListener("popstate",t.handlePopState),t.cache.clear(),t.options.plugins.forEach(e=>t.unuse(e)),Promise.resolve(t.hooks.call("disable",void 0,()=>{document.documentElement.classList.remove("swup-enabled")})).then(function(){t.hooks.clear()})}catch(t){return Promise.reject(t)}}shouldIgnoreVisit(t,e){let{el:n,event:o}=void 0===e?{}:e;const{origin:r,url:i,hash:s}=a.fromUrl(t);return r!==window.location.origin||!(!n||!this.triggerWillOpenNewWindow(n))||!!this.options.ignoreVisit(i+s,{el:n,event:o})}handleLinkClick(t){const e=t.delegateTarget,{href:n,url:o,hash:r}=a.fromElement(e);this.shouldIgnoreVisit(n,{el:e,event:t})||(this.navigating&&o===this.visit.to.url?t.preventDefault():(this.visit=this.createVisit({to:o,hash:r,el:e,event:t}),t.metaKey||t.ctrlKey||t.shiftKey||t.altKey?this.hooks.call("link:newtab",{href:n}):0===t.button&&this.hooks.callSync("link:click",{el:e,event:t},()=>{const e=this.visit.from.url??"";t.preventDefault(),o&&o!==e?this.isSameResolvedUrl(o,e)||this.performNavigation():r?this.hooks.callSync("link:anchor",{hash:r},()=>{i(o+r),this.scrollToContent()}):this.hooks.callSync("link:self",void 0,()=>"navigate"===this.options.linkToSelf?this.performNavigation():(i(o),this.scrollToContent()))})))}handlePopState(t){const e=t.state?.url??location.href;if(this.options.skipPopStateHandling(t))return;if(this.isSameResolvedUrl(o(),this.currentPageUrl))return;const{url:n,hash:r}=a.fromUrl(e);this.visit=this.createVisit({to:n,hash:r,event:t}),this.visit.history.popstate=!0;const i=t.state?.index??0;i&&i!==this.currentHistoryIndex&&(this.visit.history.direction=i-this.currentHistoryIndex>0?"forwards":"backwards",this.currentHistoryIndex=i),this.visit.animation.animate=!1,this.visit.scroll.reset=!1,this.visit.scroll.target=!1,this.options.animateHistoryBrowsing&&(this.visit.animation.animate=!0,this.visit.scroll.reset=!0),this.hooks.callSync("history:popstate",{event:t},()=>{this.performNavigation()})}triggerWillOpenNewWindow(t){return!!t.matches('[download], [target="_blank"]')}}}); | ||
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t||self).Swup=e()}(this,function(){const t=new WeakMap;function e(e,n,o,r){if(!e&&!t.has(n))return!1;const i=t.get(n)??new WeakMap;t.set(n,i);const s=i.get(o)??new Set;i.set(o,s);const a=s.has(r);return e?s.add(r):s.delete(r),a&&e}const n=(t,e)=>String(t).toLowerCase().replace(/[\s/_.]+/g,"-").replace(/[^\w-]+/g,"").replace(/--+/g,"-").replace(/^-+|-+$/g,"")||e||"",o=function(t){let{hash:e}=void 0===t?{}:t;return location.pathname+location.search+(e?location.hash:"")},r=function(t,e){void 0===e&&(e={});const n={url:t=t||o({hash:!0}),random:Math.random(),source:"swup",...e};history.pushState(n,"",t)},i=function(t,e){void 0===t&&(t=null),void 0===e&&(e={}),t=t||o({hash:!0});const n={...history.state||{},url:t,random:Math.random(),source:"swup",...e};history.replaceState(n,"",t)},s=(t,n,o,r)=>{const i=new AbortController;return function(t,n,o,r={}){const{signal:i,base:s=document}=r;if(i?.aborted)return;const{once:a,...c}=r,l=s instanceof Document?s.documentElement:s,u=Boolean("object"==typeof r?r.capture:r),h=r=>{const i=function(t,e){let n=t.target;if(n instanceof Text&&(n=n.parentElement),n instanceof Element&&t.currentTarget instanceof Element){const o=n.closest(e);if(o&&t.currentTarget.contains(o))return o}}(r,t);if(i){const t=Object.assign(r,{delegateTarget:i});o.call(l,t),a&&(l.removeEventListener(n,h,c),e(!1,l,o,d))}},d=JSON.stringify({selector:t,type:n,capture:u});e(!0,l,o,d)||l.addEventListener(n,h,c),i?.addEventListener("abort",()=>{e(!1,l,o,d)})}(t,n,o,r={...r,signal:i.signal}),{destroy:()=>i.abort()}};class a extends URL{constructor(t,e){void 0===e&&(e=document.baseURI),super(t.toString(),e),Object.setPrototypeOf(this,a.prototype)}get url(){return this.pathname+this.search}static fromElement(t){const e=t.getAttribute("href")||t.getAttribute("xlink:href")||"";return new a(e)}static fromUrl(t){return new a(t)}}const c=function(t,e){void 0===e&&(e={});try{const o=this;function n(n){const{status:i,url:s}=h;return Promise.resolve(h.text()).then(function(n){if(500===i)throw o.hooks.call("fetch:error",r,{status:i,response:h,url:s}),new l(`Server error: ${s}`,{status:i,url:s});if(!n)throw new l(`Empty response: ${s}`,{status:i,url:s});const{url:c}=a.fromUrl(s),u={url:c,html:n};return!r.cache.write||e.method&&"GET"!==e.method||t!==c||o.cache.set(u.url,u),u})}t=a.fromUrl(t).url;const{visit:r=o.visit}=e,i={...o.options.requestHeaders,...e.headers},s=e.timeout??o.options.timeout,c=new AbortController,{signal:u}=c;e={...e,headers:i,signal:u};let h,d=!1,f=null;s&&s>0&&(f=setTimeout(()=>{d=!0,c.abort("timeout")},s));const m=function(n,i){try{var s=Promise.resolve(o.hooks.call("fetch:request",r,{url:t,options:e},(t,e)=>{let{url:n,options:o}=e;return fetch(n,o)})).then(function(t){h=t,f&&clearTimeout(f)})}catch(t){return i(t)}return s&&s.then?s.then(void 0,i):s}(0,function(e){if(d)throw o.hooks.call("fetch:timeout",r,{url:t}),new l(`Request timed out: ${t}`,{url:t,timedOut:d});if("AbortError"===e?.name||u.aborted)throw new l(`Request aborted: ${t}`,{url:t,aborted:!0});throw e});return Promise.resolve(m&&m.then?m.then(n):n())}catch(p){return Promise.reject(p)}};class l extends Error{constructor(t,e){super(t),this.url=void 0,this.status=void 0,this.aborted=void 0,this.timedOut=void 0,this.name="FetchError",this.url=e.url,this.status=e.status,this.aborted=e.aborted||!1,this.timedOut=e.timedOut||!1}}class u{constructor(t){this.swup=void 0,this.pages=new Map,this.swup=t}get size(){return this.pages.size}get all(){const t=new Map;return this.pages.forEach((e,n)=>{t.set(n,{...e})}),t}has(t){return this.pages.has(this.resolve(t))}get(t){const e=this.pages.get(this.resolve(t));return e?{...e}:e}set(t,e){t=this.resolve(t),e={...e,url:t},this.pages.set(t,e),this.swup.hooks.callSync("cache:set",void 0,{page:e})}update(t,e){t=this.resolve(t);const n={...this.get(t),...e,url:t};this.pages.set(t,n)}delete(t){this.pages.delete(this.resolve(t))}clear(){this.pages.clear(),this.swup.hooks.callSync("cache:clear",void 0,void 0)}prune(t){this.pages.forEach((e,n)=>{t(n,e)&&this.delete(n)})}resolve(t){const{url:e}=a.fromUrl(t);return this.swup.resolveUrl(e)}}const h=function(t,e){return void 0===e&&(e=document),e.querySelector(t)},d=function(t,e){return void 0===e&&(e=document),Array.from(e.querySelectorAll(t))},f=()=>new Promise(t=>{requestAnimationFrame(()=>{requestAnimationFrame(()=>{t()})})});function m(t){return!!t&&("object"==typeof t||"function"==typeof t)&&"function"==typeof t.then}const p=t=>window.CSS&&window.CSS.escape?CSS.escape(t):t,v=t=>1e3*Number(t.slice(0,-1).replace(",","."));class g{constructor(t){this.swup=void 0,this.swupClasses=["to-","is-changing","is-rendering","is-popstate","is-animating","is-leaving"],this.swup=t}get selectors(){const{scope:t}=this.swup.visit.animation;return"containers"===t?this.swup.visit.containers:"html"===t?["html"]:Array.isArray(t)?t:[]}get selector(){return this.selectors.join(",")}get targets(){return this.selector.trim()?d(this.selector):[]}add(){this.targets.forEach(t=>t.classList.add(...[].slice.call(arguments)))}remove(){this.targets.forEach(t=>t.classList.remove(...[].slice.call(arguments)))}clear(){this.targets.forEach(t=>{const e=t.className.split(" ").filter(t=>this.isSwupClass(t));t.classList.remove(...e)})}isSwupClass(t){return this.swupClasses.some(e=>t.startsWith(e))}}class w{constructor(t,e){this.id=void 0,this.state=void 0,this.from=void 0,this.to=void 0,this.containers=void 0,this.animation=void 0,this.trigger=void 0,this.cache=void 0,this.history=void 0,this.scroll=void 0;const{to:n,from:o=t.currentPageUrl,hash:r,el:i,event:s}=e;this.id=Math.random(),this.state=1,this.from={url:o},this.to={url:n,hash:r},this.containers=t.options.containers,this.animation={animate:!0,wait:!1,name:void 0,native:t.options.native,scope:t.options.animationScope,selector:t.options.animationSelector},this.trigger={el:i,event:s},this.cache={read:t.options.cache,write:t.options.cache},this.history={action:"push",popstate:!1,direction:void 0},this.scroll={reset:!0,target:void 0}}advance(t){this.state<t&&(this.state=t)}abort(){this.state=8}get done(){return this.state>=7}}function y(t){return new w(this,t)}const P="undefined"!=typeof Symbol?Symbol.iterator||(Symbol.iterator=Symbol("Symbol.iterator")):"@@iterator";function k(t,e,n){if(!t.s){if(n instanceof b){if(!n.s)return void(n.o=k.bind(null,t,e));1&e&&(e=n.s),n=n.v}if(n&&n.then)return void n.then(k.bind(null,t,e),k.bind(null,t,2));t.s=e,t.v=n;const o=t.o;o&&o(t)}}const b=/*#__PURE__*/function(){function t(){}return t.prototype.then=function(e,n){const o=new t,r=this.s;if(r){const t=1&r?e:n;if(t){try{k(o,1,t(this.v))}catch(t){k(o,2,t)}return o}return this}return this.o=function(t){try{const r=t.v;1&t.s?k(o,1,e?e(r):r):n?k(o,1,n(r)):k(o,2,r)}catch(t){k(o,2,t)}},o},t}();function S(t){return t instanceof b&&1&t.s}class E{constructor(t){this.swup=void 0,this.registry=new Map,this.hooks=["animation:out:start","animation:out:await","animation:out:end","animation:in:start","animation:in:await","animation:in:end","animation:skip","cache:clear","cache:set","content:replace","content:scroll","enable","disable","fetch:request","fetch:error","fetch:timeout","history:popstate","link:click","link:self","link:anchor","link:newtab","page:load","page:view","scroll:top","scroll:anchor","visit:start","visit:transition","visit:abort","visit:end"],this.swup=t,this.init()}init(){this.hooks.forEach(t=>this.create(t))}create(t){this.registry.has(t)||this.registry.set(t,new Map)}exists(t){return this.registry.has(t)}get(t){const e=this.registry.get(t);if(e)return e;console.error(`Unknown hook '${t}'`)}clear(){this.registry.forEach(t=>t.clear())}on(t,e,n){void 0===n&&(n={});const o=this.get(t);if(!o)return console.warn(`Hook '${t}' not found.`),()=>{};const r=o.size+1,i={...n,id:r,hook:t,handler:e};return o.set(e,i),()=>this.off(t,e)}before(t,e,n){return void 0===n&&(n={}),this.on(t,e,{...n,before:!0})}replace(t,e,n){return void 0===n&&(n={}),this.on(t,e,{...n,replace:!0})}once(t,e,n){return void 0===n&&(n={}),this.on(t,e,{...n,once:!0})}off(t,e){const n=this.get(t);n&&e?n.delete(e)||console.warn(`Handler for hook '${t}' not found.`):n&&n.clear()}call(t,e,n,o){try{const r=this,[i,s,a]=r.parseCallArgs(t,e,n,o),{before:c,handler:l,after:u}=r.getHandlers(t,a);return Promise.resolve(r.run(c,i,s)).then(function(){return Promise.resolve(r.run(l,i,s)).then(function(e){let[n]=e;return Promise.resolve(r.run(u,i,s)).then(function(){return r.dispatchDomEvent(t,i,s),n})})})}catch(t){return Promise.reject(t)}}callSync(t,e,n,o){const[r,i,s]=this.parseCallArgs(t,e,n,o),{before:a,handler:c,after:l}=this.getHandlers(t,s);this.runSync(a,r,i);const[u]=this.runSync(c,r,i);return this.runSync(l,r,i),this.dispatchDomEvent(t,r,i),u}parseCallArgs(t,e,n,o){return e instanceof w||"object"!=typeof e&&"function"!=typeof n?[e,n,o]:[void 0,e,n]}run(t,e,n){try{const o=this,r=[],i=function(t,e,n){if("function"==typeof t[P]){var o,r,i,s=t[P]();if(function t(n){try{for(;!(o=s.next()).done;)if((n=e(o.value))&&n.then){if(!S(n))return void n.then(t,i||(i=k.bind(null,r=new b,2)));n=n.v}r?k(r,1,n):r=n}catch(t){k(r||(r=new b),2,t)}}(),s.return){var a=function(t){try{o.done||s.return()}catch(t){}return t};if(r&&r.then)return r.then(a,function(t){throw a(t)});a()}return r}if(!("length"in t))throw new TypeError("Object is not iterable");for(var c=[],l=0;l<t.length;l++)c.push(t[l]);return function(t,e,n){var o,r,i=-1;return function n(s){try{for(;++i<t.length;)if((s=e(i))&&s.then){if(!S(s))return void s.then(n,r||(r=k.bind(null,o=new b,2)));s=s.v}o?k(o,1,s):o=s}catch(t){k(o||(o=new b),2,t)}}(),o}(c,function(t){return e(c[t])})}(t,function(t){let{hook:i,handler:s,defaultHandler:a,once:c}=t;if(!e?.done)return c&&o.off(i,s),Promise.resolve(function(t,e){return void 0===e&&(e=[]),new Promise((n,o)=>{const r=t(...e);m(r)?r.then(n,o):n(r)})}(s,[e||o.swup.visit,n,a])).then(function(t){r.push(t)})});return Promise.resolve(i&&i.then?i.then(function(){return r}):r)}catch(t){return Promise.reject(t)}}runSync(t,e,n){const o=[];for(const{hook:r,handler:i,defaultHandler:s,once:a}of t){if(e?.done)continue;a&&this.off(r,i);const t=i(e||this.swup.visit,n,s);o.push(t),m(t)&&console.warn(`Promise returned from handler for synchronous hook '${r}'.Swup will not wait for it to resolve.`)}return o}getHandlers(t,e){const n=this.get(t);if(!n)return{found:!1,before:[],handler:[],after:[],replaced:!1};const o=Array.from(n.values()),r=this.sortRegistrations,i=o.filter(t=>{let{before:e,replace:n}=t;return e&&!n}).sort(r),s=o.filter(t=>{let{replace:e}=t;return e}).filter(t=>!0).sort(r),a=o.filter(t=>{let{before:e,replace:n}=t;return!e&&!n}).sort(r),c=s.length>0;let l=[];if(e&&(l=[{id:0,hook:t,handler:e}],c)){const n=s.length-1,o=t=>{const n=s[t-1];return n?(e,r)=>n.handler(e,r,o(t-1)):e};l=[{id:0,hook:t,handler:s[n].handler,defaultHandler:o(n)}]}return{found:!0,before:i,handler:l,after:a,replaced:c}}sortRegistrations(t,e){return(t.priority??0)-(e.priority??0)||t.id-e.id||0}dispatchDomEvent(t,e,n){if(e?.done)return;const o={hook:t,args:n,visit:e||this.swup.visit};document.dispatchEvent(new CustomEvent("swup:any",{detail:o,bubbles:!0})),document.dispatchEvent(new CustomEvent(`swup:${t}`,{detail:o,bubbles:!0}))}}const U=t=>{if(t&&"#"===t.charAt(0)&&(t=t.substring(1)),!t)return null;const e=decodeURIComponent(t);let n=document.getElementById(t)||document.getElementById(e)||h(`a[name='${p(t)}']`)||h(`a[name='${p(e)}']`);return n||"top"!==t||(n=document.body),n},C=function(t){let{elements:e,selector:n}=t;try{if(!1===n&&!e)return Promise.resolve();let t=[];if(e)t=Array.from(e);else if(n&&(t=d(n,document.body),!t.length))return console.warn(`[swup] No elements found matching animationSelector \`${n}\``),Promise.resolve();const o=t.map(t=>function(t){const{type:e,timeout:n,propCount:o}=function(t,e){const n=window.getComputedStyle(t),o=A(n,`${x}Delay`),r=A(n,`${x}Duration`),i=H(o,r),s=A(n,`${$}Delay`),a=A(n,`${$}Duration`),c=H(s,a);let l=null,u=0,h=0;return e===x?i>0&&(l=x,u=i,h=r.length):e===$?c>0&&(l=$,u=c,h=a.length):(u=Math.max(i,c),l=u>0?i>c?x:$:null,h=l?l===x?r.length:a.length:0),{type:l,timeout:u,propCount:h}}(t);return!(!e||!n)&&new Promise(r=>{const i=`${e}end`,s=performance.now();let a=0;const c=()=>{t.removeEventListener(i,l),r()},l=e=>{if(e.target===t){if(!function(t){return[`${x}end`,`${$}end`].includes(t.type)}(e))throw new Error("Not a transition or animation event.");(performance.now()-s)/1e3<e.elapsedTime||++a>=o&&c()}};setTimeout(()=>{a<o&&c()},n+1),t.addEventListener(i,l)})}(t));return o.filter(Boolean).length>0?Promise.resolve(Promise.all(o)).then(function(){}):(n&&console.warn(`[swup] No CSS animation duration defined on elements matching \`${n}\``),Promise.resolve())}catch(t){return Promise.reject(t)}},x="transition",$="animation";function A(t,e){return(t[e]||"").split(", ")}function H(t,e){for(;t.length<e.length;)t=t.concat(t);return Math.max(...e.map((e,n)=>v(e)+v(t[n])))}const T=function(t,e){void 0===e&&(e={});try{let a;const c=this;function s(s){if(a)return s;c.navigating=!0,c.visit=t;const{el:l}=t.trigger;e.referrer=e.referrer||c.currentPageUrl,!1===e.animate&&(t.animation.animate=!1),t.animation.animate||c.classes.clear();const u=e.history||l?.getAttribute("data-swup-history")||void 0;u&&["push","replace"].includes(u)&&(t.history.action=u);const h=e.animation||l?.getAttribute("data-swup-animation")||void 0;return h&&(t.animation.name=h),"object"==typeof e.cache?(t.cache.read=e.cache.read??t.cache.read,t.cache.write=e.cache.write??t.cache.write):void 0!==e.cache&&(t.cache={read:!!e.cache,write:!!e.cache}),delete e.cache,function(s,a){try{var l=Promise.resolve(c.hooks.call("visit:start",t,void 0)).then(function(){function s(){if(!t.done)return Promise.resolve(c.hooks.call("visit:transition",t,void 0,function(){try{let n;function e(e){return n?e:(t.advance(4),Promise.resolve(c.animatePageOut(t)).then(function(){function e(){return Promise.resolve(c.animatePageIn(t)).then(function(){})}const n=function(){if(t.animation.native&&document.startViewTransition)return Promise.resolve(document.startViewTransition(function(){try{const e=c.renderPage;return Promise.resolve(a).then(function(n){return Promise.resolve(e.call(c,t,n))})}catch(t){return Promise.reject(t)}}).finished).then(function(){});{const e=c.renderPage;return Promise.resolve(a).then(function(n){return Promise.resolve(e.call(c,t,n)).then(function(){})})}}();return n&&n.then?n.then(e):e()}))}const o=function(){if(!t.animation.animate)return Promise.resolve(c.hooks.call("animation:skip",void 0)).then(function(){const e=c.renderPage;return Promise.resolve(a).then(function(o){return Promise.resolve(e.call(c,t,o)).then(function(){n=1})})})}();return Promise.resolve(o&&o.then?o.then(e):e(o))}catch(r){return Promise.reject(r)}})).then(function(){if(!t.done)return Promise.resolve(c.hooks.call("visit:end",t,void 0,()=>c.classes.clear())).then(function(){t.state=7,c.navigating=!1,c.onVisitEnd&&(c.onVisitEnd(),c.onVisitEnd=void 0)})})}t.state=3;const a=c.hooks.call("page:load",t,{options:e},function(t,e){try{function n(t){return e.page=t,e.cache=!!o,e.page}let o;return t.cache.read&&(o=c.cache.get(t.to.url)),Promise.resolve(o?n(o):Promise.resolve(c.fetchPage(t.to.url,e.options)).then(n))}catch(r){return Promise.reject(r)}});if(a.then(e=>{let{html:n}=e;t.advance(5),t.to.html=n}),!t.history.popstate){const e=t.to.url+t.to.hash;"replace"===t.history.action||t.to.url===c.currentPageUrl?i(e):(c.currentHistoryIndex++,r(e,{index:c.currentHistoryIndex}))}c.currentPageUrl=o(),t.history.popstate&&c.classes.add("is-popstate"),t.animation.name&&c.classes.add(`to-${n(t.animation.name)}`);const l=function(){if(t.animation.wait)return Promise.resolve(a).then(function(){})}();return l&&l.then?l.then(s):s()})}catch(t){return a(t)}return l&&l.then?l.then(void 0,a):l}(0,function(e){e&&!e?.aborted?(t.state=9,console.error(e),c.options.skipPopStateHandling=()=>(window.location.href=t.to.url+t.to.hash,!0),window.history.go(-1)):t.state=8})}const l=function(){if(c.navigating)return function(){if(!(c.visit.state>=6))return Promise.resolve(c.hooks.call("visit:abort",c.visit,void 0)).then(function(){c.visit.state=8});t.state=2,c.onVisitEnd=()=>c.performNavigation(t,e),a=1}()}();return Promise.resolve(l&&l.then?l.then(s):s(l))}catch(u){return Promise.reject(u)}};function j(t,e,n){if(void 0===e&&(e={}),void 0===n&&(n={}),"string"!=typeof t)throw new Error("swup.navigate() requires a URL parameter");if(this.shouldIgnoreVisit(t,{el:n.el,event:n.event}))return void(window.location.href=t);const{url:o,hash:r}=a.fromUrl(t),i=this.createVisit({...n,to:o,hash:r});this.performNavigation(i,e)}const L=function(t){try{const e=this;return Promise.resolve(e.hooks.call("animation:out:start",t,void 0,()=>{e.classes.add("is-changing","is-animating","is-leaving")})).then(function(){return Promise.resolve(e.hooks.call("animation:out:await",t,{skip:!1},(t,n)=>{let{skip:o}=n;if(!o)return e.awaitAnimations({selector:t.animation.selector})})).then(function(){return Promise.resolve(e.hooks.call("animation:out:end",t,void 0)).then(function(){})})})}catch(t){return Promise.reject(t)}},q=function(t,e){let{html:n}=t,{containers:o}=void 0===e?this.options:e;const r=(new DOMParser).parseFromString(n,"text/html"),i=r.querySelector("title")?.innerText||"";document.title=i;const s=d('[data-swup-persist]:not([data-swup-persist=""])'),a=o.map(t=>{const e=document.querySelector(t),n=r.querySelector(t);return e&&n?(e.replaceWith(n),!0):(e||console.warn(`[swup] Container missing in current document: ${t}`),n||console.warn(`[swup] Container missing in incoming document: ${t}`),!1)}).filter(Boolean);return s.forEach(t=>{const e=t.getAttribute("data-swup-persist"),n=h(`[data-swup-persist="${e}"]`);n&&n!==t&&n.replaceWith(t)}),a.length===o.length},V=function(t){const e={behavior:"auto"},{target:n,reset:o}=t.scroll,r=n??t.to.hash;let i=!1;return r&&(i=this.hooks.callSync("scroll:anchor",t,{hash:r,options:e},(t,e)=>{let{hash:n,options:o}=e;const r=this.getAnchorElement(n);return r&&r.scrollIntoView(o),!!r})),o&&!i&&(i=this.hooks.callSync("scroll:top",t,{options:e},(t,e)=>{let{options:n}=e;return window.scrollTo({top:0,left:0,...n}),!0})),i},I=function(t){try{const e=this;if(t.done)return Promise.resolve();const n=e.hooks.call("animation:in:await",t,{skip:!1},(t,n)=>{let{skip:o}=n;if(!o)return e.awaitAnimations({selector:t.animation.selector})});return Promise.resolve(f()).then(function(){return Promise.resolve(e.hooks.call("animation:in:start",t,void 0,()=>{e.classes.remove("is-animating")})).then(function(){return Promise.resolve(n).then(function(){return Promise.resolve(e.hooks.call("animation:in:end",t,void 0)).then(function(){})})})})}catch(t){return Promise.reject(t)}},R=function(t,e){try{const r=this;if(t.done)return Promise.resolve();t.advance(6);const{url:s}=e;return r.classes.remove("is-leaving"),r.isSameResolvedUrl(o(),s)||(i(s),r.currentPageUrl=o(),t.to.url=r.currentPageUrl),t.animation.animate&&r.classes.add("is-rendering"),Promise.resolve(r.hooks.call("content:replace",t,{page:e},(t,e)=>{let{page:o}=e;if(!r.replaceContent(o,{containers:t.containers}))throw new Error("[swup] Container mismatch, aborting");t.animation.animate&&(r.classes.add("is-changing","is-animating","is-rendering"),t.animation.name&&r.classes.add(`to-${n(t.animation.name)}`))})).then(function(){return Promise.resolve(r.hooks.call("content:scroll",t,void 0,()=>r.scrollToContent(t))).then(function(){return Promise.resolve(r.hooks.call("page:view",t,{url:r.currentPageUrl,title:document.title})).then(function(){})})})}catch(t){return Promise.reject(t)}},N=function(t){var e;if(e=t,Boolean(e?.isSwupPlugin)){if(t.swup=this,!t._checkRequirements||t._checkRequirements())return t._beforeMount&&t._beforeMount(),t.mount(),this.plugins.push(t),this.plugins}else console.error("Not a swup plugin instance",t)};function D(t){const e=this.findPlugin(t);if(e)return e.unmount(),e._afterUnmount&&e._afterUnmount(),this.plugins=this.plugins.filter(t=>t!==e),this.plugins;console.error("No such plugin",e)}function M(t){return this.plugins.find(e=>e===t||e.name===t||e.name===`Swup${String(t)}`)}function O(t){if("function"!=typeof this.options.resolveUrl)return console.warn("[swup] options.resolveUrl expects a callback function."),t;const e=this.options.resolveUrl(t);return e&&"string"==typeof e?e.startsWith("//")||e.startsWith("http")?(console.warn("[swup] options.resolveUrl needs to return a relative url"),t):e:(console.warn("[swup] options.resolveUrl needs to return a url"),t)}function W(t,e){return this.resolveUrl(t)===this.resolveUrl(e)}const B={animateHistoryBrowsing:!1,animationSelector:'[class*="transition-"]',animationScope:"html",cache:!0,containers:["#swup"],ignoreVisit:function(t,e){let{el:n}=void 0===e?{}:e;return!!n?.closest("[data-no-swup]")},linkSelector:"a[href]",linkToSelf:"scroll",native:!1,plugins:[],resolveUrl:t=>t,requestHeaders:{"X-Requested-With":"swup",Accept:"text/html, application/xhtml+xml"},skipPopStateHandling:t=>"swup"!==t.state?.source,timeout:0};return class{constructor(t){void 0===t&&(t={}),this.version="4.5.0",this.options=void 0,this.defaults=B,this.plugins=[],this.visit=void 0,this.cache=void 0,this.hooks=void 0,this.classes=void 0,this.currentPageUrl=o(),this.currentHistoryIndex=void 0,this.clickDelegate=void 0,this.navigating=!1,this.onVisitEnd=void 0,this.use=N,this.unuse=D,this.findPlugin=M,this.log=()=>{},this.navigate=j,this.performNavigation=T,this.createVisit=y,this.delegateEvent=s,this.fetchPage=c,this.awaitAnimations=C,this.renderPage=R,this.replaceContent=q,this.animatePageIn=I,this.animatePageOut=L,this.scrollToContent=V,this.getAnchorElement=U,this.getCurrentUrl=o,this.resolveUrl=O,this.isSameResolvedUrl=W,this.options={...this.defaults,...t},this.handleLinkClick=this.handleLinkClick.bind(this),this.handlePopState=this.handlePopState.bind(this),this.cache=new u(this),this.classes=new g(this),this.hooks=new E(this),this.visit=this.createVisit({to:""}),this.currentHistoryIndex=history.state?.index??1,this.checkRequirements()&&this.enable()}checkRequirements(){return"undefined"!=typeof Promise||(console.warn("Promise is not supported"),!1)}enable(){try{const t=this,{linkSelector:e}=t.options;return t.clickDelegate=t.delegateEvent(e,"click",t.handleLinkClick),window.addEventListener("popstate",t.handlePopState),t.options.animateHistoryBrowsing&&(window.history.scrollRestoration="manual"),t.options.native=t.options.native&&!!document.startViewTransition,t.options.plugins.forEach(e=>t.use(e)),"swup"!==history.state?.source&&i(null,{index:t.currentHistoryIndex}),Promise.resolve(f()).then(function(){return Promise.resolve(t.hooks.call("enable",void 0,void 0,()=>{const e=document.documentElement;e.classList.add("swup-enabled"),e.classList.toggle("swup-native",t.options.native)})).then(function(){})})}catch(t){return Promise.reject(t)}}destroy(){try{const t=this;return t.clickDelegate.destroy(),window.removeEventListener("popstate",t.handlePopState),t.cache.clear(),t.options.plugins.forEach(e=>t.unuse(e)),Promise.resolve(t.hooks.call("disable",void 0,void 0,()=>{const t=document.documentElement;t.classList.remove("swup-enabled"),t.classList.remove("swup-native")})).then(function(){t.hooks.clear()})}catch(t){return Promise.reject(t)}}shouldIgnoreVisit(t,e){let{el:n,event:o}=void 0===e?{}:e;const{origin:r,url:i,hash:s}=a.fromUrl(t);return r!==window.location.origin||!(!n||!this.triggerWillOpenNewWindow(n))||!!this.options.ignoreVisit(i+s,{el:n,event:o})}handleLinkClick(t){const e=t.delegateTarget,{href:n,url:o,hash:r}=a.fromElement(e);if(this.shouldIgnoreVisit(n,{el:e,event:t}))return;if(this.navigating&&o===this.visit.to.url)return void t.preventDefault();const s=this.createVisit({to:o,hash:r,el:e,event:t});t.metaKey||t.ctrlKey||t.shiftKey||t.altKey?this.hooks.callSync("link:newtab",s,{href:n}):0===t.button&&this.hooks.callSync("link:click",s,{el:e,event:t},()=>{const e=s.from.url??"";t.preventDefault(),o&&o!==e?this.isSameResolvedUrl(o,e)||this.performNavigation(s):r?this.hooks.callSync("link:anchor",s,{hash:r},()=>{i(o+r),this.scrollToContent(s)}):this.hooks.callSync("link:self",s,void 0,()=>{"navigate"===this.options.linkToSelf?this.performNavigation(s):(i(o),this.scrollToContent(s))})})}handlePopState(t){const e=t.state?.url??location.href;if(this.options.skipPopStateHandling(t))return;if(this.isSameResolvedUrl(o(),this.currentPageUrl))return;const{url:n,hash:r}=a.fromUrl(e),i=this.createVisit({to:n,hash:r,event:t});i.history.popstate=!0;const s=t.state?.index??0;s&&s!==this.currentHistoryIndex&&(i.history.direction=s-this.currentHistoryIndex>0?"forwards":"backwards",this.currentHistoryIndex=s),i.animation.animate=!1,i.scroll.reset=!1,i.scroll.target=!1,this.options.animateHistoryBrowsing&&(i.animation.animate=!0,i.scroll.reset=!0),this.hooks.callSync("history:popstate",i,{event:t},()=>{this.performNavigation(i)})}triggerWillOpenNewWindow(t){return!!t.matches('[download], [target="_blank"]')}}}); | ||
//# sourceMappingURL=Swup.umd.js.map |
export { classify } from './helpers/classify.js'; | ||
export { createHistoryRecord } from './helpers/createHistoryRecord.js'; | ||
export { updateHistoryRecord } from './helpers/updateHistoryRecord.js'; | ||
export { createHistoryRecord, updateHistoryRecord } from './helpers/history.js'; | ||
export { delegateEvent } from './helpers/delegateEvent.js'; | ||
@@ -5,0 +4,0 @@ export { getCurrentUrl } from './helpers/getCurrentUrl.js'; |
import type Swup from '../Swup.js'; | ||
import type { Visit } from './Visit.js'; | ||
/** | ||
@@ -6,3 +7,3 @@ * Perform the in/enter animation of the next page. | ||
*/ | ||
export declare const animatePageIn: (this: Swup) => Promise<void>; | ||
export declare const animatePageIn: (this: Swup, visit: Visit) => Promise<void>; | ||
//# sourceMappingURL=animatePageIn.d.ts.map |
import type Swup from '../Swup.js'; | ||
import type { Visit } from './Visit.js'; | ||
/** | ||
@@ -6,3 +7,3 @@ * Perform the out/leave animation of the current page. | ||
*/ | ||
export declare const animatePageOut: (this: Swup) => Promise<void>; | ||
export declare const animatePageOut: (this: Swup, visit: Visit) => Promise<void>; | ||
//# sourceMappingURL=animatePageOut.d.ts.map |
import type { DelegateEvent } from 'delegate-it'; | ||
import type Swup from '../Swup.js'; | ||
import type { Visit } from './Visit.js'; | ||
import { Visit } from './Visit.js'; | ||
import type { FetchOptions, PageData } from './fetchPage.js'; | ||
@@ -71,6 +71,7 @@ export interface HookDefinitions { | ||
'visit:transition': undefined; | ||
'visit:abort': undefined; | ||
'visit:end': undefined; | ||
} | ||
export interface HookReturnValues { | ||
'content:scroll': Promise<boolean>; | ||
'content:scroll': Promise<boolean> | boolean; | ||
'fetch:request': Promise<Response>; | ||
@@ -80,3 +81,2 @@ 'page:load': Promise<PageData>; | ||
'scroll:anchor': boolean; | ||
'visit:transition': Promise<boolean>; | ||
} | ||
@@ -226,2 +226,3 @@ export type HookArguments<T extends HookName> = HookDefinitions[T]; | ||
* @param hook Name of the hook to trigger | ||
* @param visit The visit object this hook belongs to | ||
* @param args Arguments to pass to the handler | ||
@@ -231,2 +232,3 @@ * @param defaultHandler A default implementation of this hook to execute | ||
*/ | ||
call<T extends HookName>(hook: T, visit: Visit | undefined, args: HookArguments<T>, defaultHandler?: HookDefaultHandler<T>): Promise<Awaited<ReturnType<HookDefaultHandler<T>>>>; | ||
call<T extends HookName>(hook: T, args: HookArguments<T>, defaultHandler?: HookDefaultHandler<T>): Promise<Awaited<ReturnType<HookDefaultHandler<T>>>>; | ||
@@ -237,2 +239,3 @@ /** | ||
* @param hook Name of the hook to trigger | ||
* @param visit The visit object this hook belongs to | ||
* @param args Arguments to pass to the handler | ||
@@ -242,4 +245,9 @@ * @param defaultHandler A default implementation of this hook to execute | ||
*/ | ||
callSync<T extends HookName>(hook: T, visit: Visit | undefined, args: HookArguments<T>, defaultHandler?: HookDefaultHandler<T>): ReturnType<HookDefaultHandler<T>>; | ||
callSync<T extends HookName>(hook: T, args: HookArguments<T>, defaultHandler?: HookDefaultHandler<T>): ReturnType<HookDefaultHandler<T>>; | ||
/** | ||
* Parse the call arguments for call() and callSync() to allow legacy argument order. | ||
*/ | ||
protected parseCallArgs<T extends HookName>(hook: T, arg1: Visit | HookArguments<T> | undefined, arg2: HookArguments<T> | HookDefaultHandler<T>, arg3?: HookDefaultHandler<T>): [Visit | undefined, HookArguments<T>, HookDefaultHandler<T> | undefined]; | ||
/** | ||
* Execute the handlers for a hook, in order, as `Promise`s that will be `await`ed. | ||
@@ -249,4 +257,4 @@ * @param registrations The registrations (handler + options) to execute | ||
*/ | ||
protected run<T extends HookName>(registrations: HookRegistration<T, HookDefaultHandler<T>>[], args: HookArguments<T>): Promise<Awaited<ReturnType<HookDefaultHandler<T>>>[]>; | ||
protected run<T extends HookName>(registrations: HookRegistration<T>[], args: HookArguments<T>): Promise<unknown[]>; | ||
protected run<T extends HookName>(registrations: HookRegistration<T, HookDefaultHandler<T>>[], visit: Visit | undefined, args: HookArguments<T>): Promise<Awaited<ReturnType<HookDefaultHandler<T>>>[]>; | ||
protected run<T extends HookName>(registrations: HookRegistration<T>[], visit: Visit | undefined, args: HookArguments<T>): Promise<unknown[]>; | ||
/** | ||
@@ -257,4 +265,4 @@ * Execute the handlers for a hook, in order, without `await`ing any returned `Promise`s. | ||
*/ | ||
protected runSync<T extends HookName>(registrations: HookRegistration<T, HookDefaultHandler<T>>[], args: HookArguments<T>): ReturnType<HookDefaultHandler<T>>[]; | ||
protected runSync<T extends HookName>(registrations: HookRegistration<T>[], args: HookArguments<T>): unknown[]; | ||
protected runSync<T extends HookName>(registrations: HookRegistration<T, HookDefaultHandler<T>>[], visit: Visit | undefined, args: HookArguments<T>): ReturnType<HookDefaultHandler<T>>[]; | ||
protected runSync<T extends HookName>(registrations: HookRegistration<T>[], visit: Visit | undefined, args: HookArguments<T>): unknown[]; | ||
/** | ||
@@ -285,5 +293,5 @@ * Get all registered handlers for a hook, sorted by priority and registration order. | ||
*/ | ||
protected dispatchDomEvent<T extends HookName>(hook: T, args?: HookArguments<T>): void; | ||
protected dispatchDomEvent<T extends HookName>(hook: T, visit: Visit | undefined, args?: HookArguments<T>): void; | ||
} | ||
export {}; | ||
//# sourceMappingURL=Hooks.d.ts.map |
import type Swup from '../Swup.js'; | ||
import { type FetchOptions } from './fetchPage.js'; | ||
import type { VisitInitOptions } from './Visit.js'; | ||
import { type VisitInitOptions, type Visit } from './Visit.js'; | ||
export type HistoryAction = 'push' | 'replace'; | ||
@@ -40,4 +40,4 @@ export type HistoryDirection = 'forwards' | 'backwards'; | ||
*/ | ||
export declare function performNavigation(this: Swup, options?: NavigationOptions & FetchOptions): Promise<void>; | ||
export declare function performNavigation(this: Swup, visit: Visit, options?: NavigationOptions & FetchOptions): Promise<void>; | ||
export {}; | ||
//# sourceMappingURL=navigate.d.ts.map |
import type Swup from '../Swup.js'; | ||
import type { PageData } from './fetchPage.js'; | ||
import { type Visit } from './Visit.js'; | ||
/** | ||
* Render the next page: replace the content and update scroll position. | ||
*/ | ||
export declare const renderPage: (this: Swup, page: PageData) => Promise<void>; | ||
export declare const renderPage: (this: Swup, visit: Visit, page: PageData) => Promise<void>; | ||
//# sourceMappingURL=renderPage.d.ts.map |
import type Swup from '../Swup.js'; | ||
import type { Visit } from './Visit.js'; | ||
/** | ||
@@ -6,3 +7,3 @@ * Update the scroll position after page render. | ||
*/ | ||
export declare const scrollToContent: (this: Swup) => boolean; | ||
export declare const scrollToContent: (this: Swup, visit: Visit) => boolean; | ||
//# sourceMappingURL=scrollToContent.d.ts.map |
import type Swup from '../Swup.js'; | ||
import type { Options } from '../Swup.js'; | ||
import type { HistoryAction, HistoryDirection } from './navigate.js'; | ||
/** An object holding details about the current visit. */ | ||
export interface Visit { | ||
/** A unique ID to identify this visit */ | ||
id: number; | ||
/** The previous page, about to leave */ | ||
from: VisitFrom; | ||
/** The next page, about to enter */ | ||
to: VisitTo; | ||
/** The content containers, about to be replaced */ | ||
containers: Options['containers']; | ||
/** Information about animated page transitions */ | ||
animation: VisitAnimation; | ||
/** What triggered this visit */ | ||
trigger: VisitTrigger; | ||
/** Cache behavior for this visit */ | ||
cache: VisitCache; | ||
/** Browser history behavior on this visit */ | ||
history: VisitHistory; | ||
/** Scroll behavior on this visit */ | ||
scroll: VisitScroll; | ||
} | ||
/** See below for the class Visit {} definition */ | ||
export interface VisitFrom { | ||
@@ -44,2 +24,4 @@ /** The URL of the previous page */ | ||
name?: string; | ||
/** Whether this animation uses the native browser ViewTransition API. Default: `false` */ | ||
native: boolean; | ||
/** Elements on which to add animation classes. Default: `html` element */ | ||
@@ -83,4 +65,28 @@ scope: 'html' | 'containers' | string[]; | ||
} | ||
/** An object holding details about the current visit. */ | ||
export declare class Visit { | ||
/** A unique ID to identify this visit */ | ||
id: number; | ||
/** The previous page, about to leave */ | ||
from: VisitFrom; | ||
/** The next page, about to enter */ | ||
to: VisitTo; | ||
/** The content containers, about to be replaced */ | ||
containers: Options['containers']; | ||
/** Information about animated page transitions */ | ||
animation: VisitAnimation; | ||
/** What triggered this visit */ | ||
trigger: VisitTrigger; | ||
/** Cache behavior for this visit */ | ||
cache: VisitCache; | ||
/** Browser history behavior on this visit */ | ||
history: VisitHistory; | ||
/** Scroll behavior on this visit */ | ||
scroll: VisitScroll; | ||
constructor(swup: Swup, options: VisitInitOptions); | ||
/** Is this visit done, i.e. completed, failed, or aborted? */ | ||
get done(): boolean; | ||
} | ||
/** Create a new visit object. */ | ||
export declare function createVisit(this: Swup, { to, from, hash, el, event }: VisitInitOptions): Visit; | ||
export declare function createVisit(this: Swup, options: VisitInitOptions): Visit; | ||
//# sourceMappingURL=Visit.d.ts.map |
@@ -33,2 +33,4 @@ import { type DelegateEvent } from 'delegate-it'; | ||
linkToSelf: NavigationToSelfAction; | ||
/** Enable native animations using the View Transitions API. */ | ||
native: boolean; | ||
/** Plugins to register on startup. */ | ||
@@ -71,2 +73,4 @@ plugins: Plugin[]; | ||
protected navigating: boolean; | ||
/** Run anytime a visit ends */ | ||
protected onVisitEnd?: () => Promise<unknown>; | ||
/** Install a plugin */ | ||
@@ -92,3 +96,3 @@ use: (this: Swup, plugin: unknown) => Plugin[] | undefined; | ||
awaitAnimations: typeof awaitAnimations; | ||
protected renderPage: (this: Swup, page: import("./modules/fetchPage.js").PageData) => Promise<void>; | ||
protected renderPage: (this: Swup, visit: Visit, page: import("./modules/fetchPage.js").PageData) => Promise<void>; | ||
/** Replace the content after page load */ | ||
@@ -98,5 +102,5 @@ replaceContent: (this: Swup, { html }: import("./modules/fetchPage.js").PageData, { containers }?: { | ||
}) => boolean; | ||
protected animatePageIn: (this: Swup) => Promise<void>; | ||
protected animatePageOut: (this: Swup) => Promise<void>; | ||
protected scrollToContent: (this: Swup) => boolean; | ||
protected animatePageIn: (this: Swup, visit: Visit) => Promise<void>; | ||
protected animatePageOut: (this: Swup, visit: Visit) => Promise<void>; | ||
protected scrollToContent: (this: Swup, visit: Visit) => boolean; | ||
/** Find the anchor element for a given hash */ | ||
@@ -103,0 +107,0 @@ getAnchorElement: (hash?: string | undefined) => Element | null; |
{ | ||
"name": "swup", | ||
"amdName": "Swup", | ||
"version": "4.4.4", | ||
"version": "4.5.0", | ||
"description": "Versatile and extensible page transition library for server-rendered websites", | ||
@@ -70,2 +70,3 @@ "type": "module", | ||
"@swup/prettier-config": "^1.0.0", | ||
"@types/dom-view-transitions": "^1.0.2", | ||
"@types/jsdom": "^21.1.1", | ||
@@ -72,0 +73,0 @@ "@typescript-eslint/eslint-plugin": "^6.3.0", |
@@ -5,4 +5,3 @@ // Re-export all helpers to allow custom package export path | ||
export { classify } from './helpers/classify.js'; | ||
export { createHistoryRecord } from './helpers/createHistoryRecord.js'; | ||
export { updateHistoryRecord } from './helpers/updateHistoryRecord.js'; | ||
export { createHistoryRecord, updateHistoryRecord } from './helpers/history.js'; | ||
export { delegateEvent } from './helpers/delegateEvent.js'; | ||
@@ -9,0 +8,0 @@ export { getCurrentUrl } from './helpers/getCurrentUrl.js'; |
@@ -9,2 +9,3 @@ /** | ||
super(url.toString(), base); | ||
// Fix Safari bug with extending native classes | ||
Object.setPrototypeOf(this, Location.prototype); | ||
@@ -11,0 +12,0 @@ } |
import type Swup from '../Swup.js'; | ||
import { nextTick } from '../utils.js'; | ||
import type { Visit } from './Visit.js'; | ||
@@ -8,13 +9,13 @@ /** | ||
*/ | ||
export const animatePageIn = async function (this: Swup) { | ||
if (!this.visit.animation.animate) { | ||
return; | ||
} | ||
export const animatePageIn = async function (this: Swup, visit: Visit) { | ||
// Check if failed/aborted in the meantime | ||
if (visit.done) return; | ||
const animation = this.hooks.call( | ||
'animation:in:await', | ||
visit, | ||
{ skip: false }, | ||
async (visit, { skip }) => { | ||
(visit, { skip }) => { | ||
if (skip) return; | ||
await this.awaitAnimations({ selector: visit.animation.selector }); | ||
return this.awaitAnimations({ selector: visit.animation.selector }); | ||
} | ||
@@ -25,3 +26,3 @@ ); | ||
await this.hooks.call('animation:in:start', undefined, () => { | ||
await this.hooks.call('animation:in:start', visit, undefined, () => { | ||
this.classes.remove('is-animating'); | ||
@@ -32,3 +33,3 @@ }); | ||
await this.hooks.call('animation:in:end', undefined); | ||
await this.hooks.call('animation:in:end', visit, undefined); | ||
}; |
import type Swup from '../Swup.js'; | ||
import { classify } from '../helpers.js'; | ||
import type { Visit } from './Visit.js'; | ||
@@ -8,24 +8,13 @@ /** | ||
*/ | ||
export const animatePageOut = async function (this: Swup) { | ||
if (!this.visit.animation.animate) { | ||
await this.hooks.call('animation:skip', undefined); | ||
return; | ||
} | ||
await this.hooks.call('animation:out:start', undefined, (visit) => { | ||
this.classes.add('is-changing', 'is-leaving', 'is-animating'); | ||
if (visit.history.popstate) { | ||
this.classes.add('is-popstate'); | ||
} | ||
if (visit.animation.name) { | ||
this.classes.add(`to-${classify(visit.animation.name)}`); | ||
} | ||
export const animatePageOut = async function (this: Swup, visit: Visit) { | ||
await this.hooks.call('animation:out:start', visit, undefined, () => { | ||
this.classes.add('is-changing', 'is-animating', 'is-leaving'); | ||
}); | ||
await this.hooks.call('animation:out:await', { skip: false }, async (visit, { skip }) => { | ||
await this.hooks.call('animation:out:await', visit, { skip: false }, (visit, { skip }) => { | ||
if (skip) return; | ||
await this.awaitAnimations({ selector: visit.animation.selector }); | ||
return this.awaitAnimations({ selector: visit.animation.selector }); | ||
}); | ||
await this.hooks.call('animation:out:end', undefined); | ||
await this.hooks.call('animation:out:end', visit, undefined); | ||
}; |
@@ -52,3 +52,3 @@ import type Swup from '../Swup.js'; | ||
this.pages.set(url, page); | ||
this.swup.hooks.callSync('cache:set', { page }); | ||
this.swup.hooks.callSync('cache:set', undefined, { page }); | ||
} | ||
@@ -71,3 +71,3 @@ | ||
this.pages.clear(); | ||
this.swup.hooks.callSync('cache:clear', undefined); | ||
this.swup.hooks.callSync('cache:clear', undefined, undefined); | ||
} | ||
@@ -74,0 +74,0 @@ |
@@ -6,3 +6,10 @@ import type Swup from '../Swup.js'; | ||
protected swup: Swup; | ||
protected swupClasses = ['to-', 'is-changing', 'is-rendering', 'is-popstate', 'is-animating']; | ||
protected swupClasses = [ | ||
'to-', | ||
'is-changing', | ||
'is-rendering', | ||
'is-popstate', | ||
'is-animating', | ||
'is-leaving' | ||
]; | ||
@@ -9,0 +16,0 @@ constructor(swup: Swup) { |
import type Swup from '../Swup.js'; | ||
import { Location } from '../helpers.js'; | ||
import type { Visit } from './Visit.js'; | ||
@@ -20,2 +21,4 @@ /** A page object as used by swup and its cache. */ | ||
timeout?: number; | ||
/** Optional visit object with additional context. @internal */ | ||
visit?: Visit; | ||
} | ||
@@ -51,2 +54,3 @@ | ||
const { visit = this.visit } = options; | ||
const headers = { ...this.options.requestHeaders, ...options.headers }; | ||
@@ -72,2 +76,3 @@ const timeout = options.timeout ?? this.options.timeout; | ||
'fetch:request', | ||
visit, | ||
{ url, options }, | ||
@@ -81,10 +86,7 @@ (visit, { url, options }) => fetch(url, options) | ||
if (timedOut) { | ||
this.hooks.call('fetch:timeout', { url }); | ||
this.hooks.call('fetch:timeout', visit, { url }); | ||
throw new FetchError(`Request timed out: ${url}`, { url, timedOut }); | ||
} | ||
if ((error as Error)?.name === 'AbortError' || signal.aborted) { | ||
throw new FetchError(`Request aborted: ${url}`, { | ||
url: url, | ||
aborted: true | ||
}); | ||
throw new FetchError(`Request aborted: ${url}`, { url, aborted: true }); | ||
} | ||
@@ -98,3 +100,3 @@ throw error; | ||
if (status === 500) { | ||
this.hooks.call('fetch:error', { status, response, url: responseUrl }); | ||
this.hooks.call('fetch:error', visit, { status, response, url: responseUrl }); | ||
throw new FetchError(`Server error: ${responseUrl}`, { status, url: responseUrl }); | ||
@@ -112,7 +114,3 @@ } | ||
// Write to cache for safe methods and non-redirects | ||
if ( | ||
this.visit.cache.write && | ||
(!options.method || options.method === 'GET') && | ||
url === finalUrl | ||
) { | ||
if (visit.cache.write && (!options.method || options.method === 'GET') && url === finalUrl) { | ||
this.cache.set(page.url, page); | ||
@@ -119,0 +117,0 @@ } |
@@ -5,3 +5,3 @@ import type { DelegateEvent } from 'delegate-it'; | ||
import { isPromise, runAsPromise } from '../utils.js'; | ||
import type { Visit } from './Visit.js'; | ||
import { Visit } from './Visit.js'; | ||
import type { FetchOptions, PageData } from './fetchPage.js'; | ||
@@ -37,2 +37,3 @@ | ||
'visit:transition': undefined; | ||
'visit:abort': undefined; | ||
'visit:end': undefined; | ||
@@ -42,3 +43,3 @@ } | ||
export interface HookReturnValues { | ||
'content:scroll': Promise<boolean>; | ||
'content:scroll': Promise<boolean> | boolean; | ||
'fetch:request': Promise<Response>; | ||
@@ -48,3 +49,2 @@ 'page:load': Promise<PageData>; | ||
'scroll:anchor': boolean; | ||
'visit:transition': Promise<boolean>; | ||
} | ||
@@ -161,2 +161,3 @@ | ||
'visit:transition', | ||
'visit:abort', | ||
'visit:end' | ||
@@ -341,2 +342,3 @@ ]; | ||
* @param hook Name of the hook to trigger | ||
* @param visit The visit object this hook belongs to | ||
* @param args Arguments to pass to the handler | ||
@@ -346,12 +348,20 @@ * @param defaultHandler A default implementation of this hook to execute | ||
*/ | ||
// Overload: default order of arguments | ||
async call<T extends HookName>(hook: T, visit: Visit | undefined, args: HookArguments<T>, defaultHandler?: HookDefaultHandler<T>): Promise<Awaited<ReturnType<HookDefaultHandler<T>>>>; // prettier-ignore | ||
// Overload: legacy order of arguments, with visit missing | ||
async call<T extends HookName>(hook: T, args: HookArguments<T>, defaultHandler?: HookDefaultHandler<T>): Promise<Awaited<ReturnType<HookDefaultHandler<T>>>>; // prettier-ignore | ||
// Implementation | ||
async call<T extends HookName>( | ||
hook: T, | ||
args: HookArguments<T>, | ||
defaultHandler?: HookDefaultHandler<T> | ||
arg1: Visit | HookArguments<T>, | ||
arg2: HookArguments<T> | HookDefaultHandler<T>, | ||
arg3?: HookDefaultHandler<T> | ||
): Promise<Awaited<ReturnType<HookDefaultHandler<T>>>> { | ||
const [visit, args, defaultHandler] = this.parseCallArgs(hook, arg1, arg2, arg3); | ||
const { before, handler, after } = this.getHandlers(hook, defaultHandler); | ||
await this.run(before, args); | ||
const [result] = await this.run(handler, args); | ||
await this.run(after, args); | ||
this.dispatchDomEvent(hook, args); | ||
await this.run(before, visit, args); | ||
const [result] = await this.run(handler, visit, args); | ||
await this.run(after, visit, args); | ||
this.dispatchDomEvent(hook, visit, args); | ||
return result; | ||
@@ -364,2 +374,3 @@ } | ||
* @param hook Name of the hook to trigger | ||
* @param visit The visit object this hook belongs to | ||
* @param args Arguments to pass to the handler | ||
@@ -369,12 +380,19 @@ * @param defaultHandler A default implementation of this hook to execute | ||
*/ | ||
// Overload: default order of arguments | ||
callSync<T extends HookName>(hook: T, visit: Visit | undefined, args: HookArguments<T>, defaultHandler?: HookDefaultHandler<T>): ReturnType<HookDefaultHandler<T>>; // prettier-ignore | ||
// Overload: legacy order of arguments, with visit missing | ||
callSync<T extends HookName>(hook: T, args: HookArguments<T>, defaultHandler?: HookDefaultHandler<T>): ReturnType<HookDefaultHandler<T>>; // prettier-ignore | ||
// Implementation | ||
callSync<T extends HookName>( | ||
hook: T, | ||
args: HookArguments<T>, | ||
defaultHandler?: HookDefaultHandler<T> | ||
arg1: Visit | HookArguments<T>, | ||
arg2: HookArguments<T> | HookDefaultHandler<T>, | ||
arg3?: HookDefaultHandler<T> | ||
): ReturnType<HookDefaultHandler<T>> { | ||
const [visit, args, defaultHandler] = this.parseCallArgs(hook, arg1, arg2, arg3); | ||
const { before, handler, after } = this.getHandlers(hook, defaultHandler); | ||
this.runSync(before, args); | ||
const [result] = this.runSync(handler, args); | ||
this.runSync(after, args); | ||
this.dispatchDomEvent(hook, args); | ||
this.runSync(before, visit, args); | ||
const [result] = this.runSync(handler, visit, args); | ||
this.runSync(after, visit, args); | ||
this.dispatchDomEvent(hook, visit, args); | ||
return result; | ||
@@ -384,2 +402,22 @@ } | ||
/** | ||
* Parse the call arguments for call() and callSync() to allow legacy argument order. | ||
*/ | ||
protected parseCallArgs<T extends HookName>( | ||
hook: T, | ||
arg1: Visit | HookArguments<T> | undefined, | ||
arg2: HookArguments<T> | HookDefaultHandler<T>, | ||
arg3?: HookDefaultHandler<T> | ||
): [Visit | undefined, HookArguments<T>, HookDefaultHandler<T> | undefined] { | ||
const isLegacyOrder = | ||
!(arg1 instanceof Visit) && (typeof arg1 === 'object' || typeof arg2 === 'function'); | ||
if (isLegacyOrder) { | ||
// Legacy positioning: arguments in second or handler passed in third place | ||
return [undefined, arg1 as HookArguments<T>, arg2 as HookDefaultHandler<T>]; | ||
} else { | ||
// Default positioning: visit passed in as first argument | ||
return [arg1, arg2 as HookArguments<T>, arg3]; | ||
} | ||
} | ||
/** | ||
* Execute the handlers for a hook, in order, as `Promise`s that will be `await`ed. | ||
@@ -391,8 +429,9 @@ * @param registrations The registrations (handler + options) to execute | ||
// Overload: running HookDefaultHandler: expect HookDefaultHandler return type | ||
protected async run<T extends HookName>(registrations: HookRegistration<T, HookDefaultHandler<T>>[], args: HookArguments<T>): Promise<Awaited<ReturnType<HookDefaultHandler<T>>>[]>; // prettier-ignore | ||
protected async run<T extends HookName>(registrations: HookRegistration<T, HookDefaultHandler<T>>[], visit: Visit | undefined, args: HookArguments<T>): Promise<Awaited<ReturnType<HookDefaultHandler<T>>>[]>; // prettier-ignore | ||
// Overload: running user handler: expect no specific type | ||
protected async run<T extends HookName>(registrations: HookRegistration<T>[], args: HookArguments<T>): Promise<unknown[]>; // prettier-ignore | ||
protected async run<T extends HookName>(registrations: HookRegistration<T>[], visit: Visit | undefined, args: HookArguments<T>): Promise<unknown[]>; // prettier-ignore | ||
// Implementation | ||
protected async run<T extends HookName, R extends HookRegistration<T>[]>( | ||
registrations: R, | ||
visit: Visit | undefined, | ||
args: HookArguments<T> | ||
@@ -402,7 +441,10 @@ ): Promise<Awaited<ReturnType<HookDefaultHandler<T>>> | unknown[]> { | ||
for (const { hook, handler, defaultHandler, once } of registrations) { | ||
const result = await runAsPromise(handler, [this.swup.visit, args, defaultHandler]); | ||
if (visit?.done) continue; | ||
if (once) this.off(hook, handler); | ||
const result = await runAsPromise(handler, [ | ||
visit || this.swup.visit, | ||
args, | ||
defaultHandler | ||
]); | ||
results.push(result); | ||
if (once) { | ||
this.off(hook, handler); | ||
} | ||
} | ||
@@ -419,8 +461,9 @@ return results; | ||
// Overload: running HookDefaultHandler: expect HookDefaultHandler return type | ||
protected runSync<T extends HookName>(registrations: HookRegistration<T, HookDefaultHandler<T>>[], args: HookArguments<T> ): ReturnType<HookDefaultHandler<T>>[]; // prettier-ignore | ||
protected runSync<T extends HookName>(registrations: HookRegistration<T, HookDefaultHandler<T>>[], visit: Visit | undefined, args: HookArguments<T> ): ReturnType<HookDefaultHandler<T>>[]; // prettier-ignore | ||
// Overload: running user handler: expect no specific type | ||
protected runSync<T extends HookName>(registrations: HookRegistration<T>[], args: HookArguments<T>): unknown[]; // prettier-ignore | ||
protected runSync<T extends HookName>(registrations: HookRegistration<T>[], visit: Visit | undefined, args: HookArguments<T>): unknown[]; // prettier-ignore | ||
// Implementation | ||
protected runSync<T extends HookName, R extends HookRegistration<T>[]>( | ||
registrations: R, | ||
visit: Visit | undefined, | ||
args: HookArguments<T> | ||
@@ -430,3 +473,5 @@ ): (ReturnType<HookDefaultHandler<T>> | unknown)[] { | ||
for (const { hook, handler, defaultHandler, once } of registrations) { | ||
const result = (handler as HookDefaultHandler<T>)(this.swup.visit, args, defaultHandler); // prettier-ignore | ||
if (visit?.done) continue; | ||
if (once) this.off(hook, handler); | ||
const result = (handler as HookDefaultHandler<T>)(visit || this.swup.visit, args, defaultHandler); // prettier-ignore | ||
results.push(result); | ||
@@ -439,5 +484,2 @@ if (isPromise(result)) { | ||
} | ||
if (once) { | ||
this.off(hook, handler); | ||
} | ||
} | ||
@@ -518,4 +560,10 @@ return results; | ||
*/ | ||
protected dispatchDomEvent<T extends HookName>(hook: T, args?: HookArguments<T>): void { | ||
const detail: HookEventDetail = { hook, args, visit: this.swup.visit }; | ||
protected dispatchDomEvent<T extends HookName>( | ||
hook: T, | ||
visit: Visit | undefined, | ||
args?: HookArguments<T> | ||
): void { | ||
if (visit?.done) return; | ||
const detail: HookEventDetail = { hook, args, visit: visit || this.swup.visit }; | ||
document.dispatchEvent( | ||
@@ -522,0 +570,0 @@ new CustomEvent<HookEventDetail>(`swup:any`, { detail, bubbles: true }) |
import type Swup from '../Swup.js'; | ||
import { createHistoryRecord, updateHistoryRecord, getCurrentUrl, Location } from '../helpers.js'; | ||
import { FetchError, type FetchOptions, type PageData } from './fetchPage.js'; | ||
import type { VisitInitOptions } from './Visit.js'; | ||
import { type VisitInitOptions, type Visit, VisitState } from './Visit.js'; | ||
import { | ||
createHistoryRecord, | ||
updateHistoryRecord, | ||
getCurrentUrl, | ||
Location, | ||
classify | ||
} from '../helpers.js'; | ||
@@ -46,4 +52,5 @@ export type HistoryAction = 'push' | 'replace'; | ||
const { url: to, hash } = Location.fromUrl(url); | ||
this.visit = this.createVisit({ ...init, to, hash }); | ||
this.performNavigation(options); | ||
const visit = this.createVisit({ ...init, to, hash }); | ||
this.performNavigation(visit, options); | ||
} | ||
@@ -64,8 +71,20 @@ | ||
this: Swup, | ||
visit: Visit, | ||
options: NavigationOptions & FetchOptions = {} | ||
): Promise<void> { | ||
if (this.navigating) { | ||
if (this.visit.state >= VisitState.ENTERING) { | ||
// Currently navigating and content already loaded? Finish and queue | ||
visit.state = VisitState.QUEUED; | ||
this.onVisitEnd = () => this.performNavigation(visit, options); | ||
return; | ||
} else { | ||
// Currently navigating and content not loaded? Abort running visit | ||
await this.hooks.call('visit:abort', this.visit, undefined); | ||
this.visit.state = VisitState.ABORTED; | ||
} | ||
} | ||
this.navigating = true; | ||
// Save this localy to a) allow ignoring the visit if a new one was started in the meantime | ||
// and b) avoid unintended modifications to any newer visits | ||
const visit = this.visit; | ||
this.visit = visit; | ||
@@ -107,6 +126,7 @@ const { el } = visit.trigger; | ||
try { | ||
await this.hooks.call('visit:start', undefined); | ||
await this.hooks.call('visit:start', visit, undefined); | ||
visit.state = VisitState.STARTED; | ||
// Begin loading page | ||
const pagePromise = this.hooks.call('page:load', { options }, async (visit, args) => { | ||
const page = this.hooks.call('page:load', visit, { options }, async (visit, args) => { | ||
// Read from cache | ||
@@ -124,2 +144,8 @@ let cachedPage: PageData | undefined; | ||
// When page loaded: mark visit as loaded, save html into visit object | ||
page.then(({ html }) => { | ||
visit.advance(VisitState.LOADED); | ||
visit.to.html = html; | ||
}); | ||
// Create/update history record if this is not a popstate call or leads to the same URL | ||
@@ -139,44 +165,62 @@ if (!visit.history.popstate) { | ||
// Mark visit type with classes | ||
if (visit.history.popstate) { | ||
this.classes.add('is-popstate'); | ||
} | ||
if (visit.animation.name) { | ||
this.classes.add(`to-${classify(visit.animation.name)}`); | ||
} | ||
// Wait for page before starting to animate out? | ||
if (visit.animation.wait) { | ||
const { html } = await pagePromise; | ||
visit.to.html = html; | ||
await page; | ||
} | ||
// perform the actual transition: animate and replace content | ||
await this.hooks.call('visit:transition', undefined, async (visit) => { | ||
// Start leave animation | ||
const animationPromise = this.animatePageOut(); | ||
// Check if failed/aborted in the meantime | ||
if (visit.done) return; | ||
// Wait for page to load and leave animation to finish | ||
const [page] = await Promise.all([pagePromise, animationPromise]); | ||
// Perform the actual transition: animate and replace content | ||
await this.hooks.call('visit:transition', visit, undefined, async () => { | ||
// No animation? Just await page and render | ||
if (!visit.animation.animate) { | ||
await this.hooks.call('animation:skip', undefined); | ||
await this.renderPage(visit, await page); | ||
return; | ||
} | ||
// Abort if another visit was started in the meantime | ||
if (visit.id !== this.visit.id) { | ||
return false; | ||
// Animate page out, render page, animate page in | ||
visit.advance(VisitState.LEAVING); | ||
await this.animatePageOut(visit); | ||
if (visit.animation.native && document.startViewTransition) { | ||
await document.startViewTransition( | ||
async () => await this.renderPage(visit, await page) | ||
).finished; | ||
} else { | ||
await this.renderPage(visit, await page); | ||
} | ||
await this.animatePageIn(visit); | ||
}); | ||
// Render page: replace content and scroll to top/fragment | ||
await this.renderPage(page); | ||
// Check if failed/aborted in the meantime | ||
if (visit.done) return; | ||
// Wait for enter animation | ||
await this.animatePageIn(); | ||
return true; | ||
}); | ||
// Finalize visit | ||
await this.hooks.call('visit:end', undefined, () => this.classes.clear()); | ||
await this.hooks.call('visit:end', visit, undefined, () => this.classes.clear()); | ||
visit.state = VisitState.COMPLETED; | ||
this.navigating = false; | ||
// Reset visit info after finish? | ||
// if (visit.to && this.isSameResolvedUrl(visit.to.url, requestedUrl)) { | ||
// this.visit = this.createVisit({ to: undefined }); | ||
// } | ||
this.navigating = false; | ||
/** Run eventually queued function */ | ||
if (this.onVisitEnd) { | ||
this.onVisitEnd(); | ||
this.onVisitEnd = undefined; | ||
} | ||
} catch (error) { | ||
// Return early if error is undefined or signals an aborted request | ||
if (!error || (error as FetchError)?.aborted) { | ||
visit.state = VisitState.ABORTED; | ||
return; | ||
} | ||
visit.state = VisitState.FAILED; | ||
// Log to console as we swallow almost all hook errors | ||
@@ -183,0 +227,0 @@ console.error(error); |
import { updateHistoryRecord, getCurrentUrl, classify } from '../helpers.js'; | ||
import type Swup from '../Swup.js'; | ||
import type { PageData } from './fetchPage.js'; | ||
import { VisitState, type Visit } from './Visit.js'; | ||
@@ -8,5 +9,10 @@ /** | ||
*/ | ||
export const renderPage = async function (this: Swup, page: PageData): Promise<void> { | ||
const { url, html } = page; | ||
export const renderPage = async function (this: Swup, visit: Visit, page: PageData): Promise<void> { | ||
// Check if failed/aborted in the meantime | ||
if (visit.done) return; | ||
visit.advance(VisitState.ENTERING); | ||
const { url } = page; | ||
this.classes.remove('is-leaving'); | ||
@@ -18,15 +24,12 @@ | ||
this.currentPageUrl = getCurrentUrl(); | ||
this.visit.to.url = this.currentPageUrl; | ||
visit.to.url = this.currentPageUrl; | ||
} | ||
// only add for animated page loads | ||
if (this.visit.animation.animate) { | ||
if (visit.animation.animate) { | ||
this.classes.add('is-rendering'); | ||
} | ||
// save html into visit context for easier retrieval | ||
this.visit.to.html = html; | ||
// replace content: allow handlers and plugins to overwrite paga data and containers | ||
await this.hooks.call('content:replace', { page }, (visit, { page }) => { | ||
await this.hooks.call('content:replace', visit, { page }, (visit, { page }) => { | ||
const success = this.replaceContent(page, { containers: visit.containers }); | ||
@@ -38,3 +41,3 @@ if (!success) { | ||
// Make sure to add these classes to new containers as well | ||
this.classes.add('is-animating', 'is-changing', 'is-rendering'); | ||
this.classes.add('is-changing', 'is-animating', 'is-rendering'); | ||
if (visit.animation.name) { | ||
@@ -47,8 +50,7 @@ this.classes.add(`to-${classify(visit.animation.name)}`); | ||
// scroll into view: either anchor or top of page | ||
// @ts-ignore: not returning a promise is intentional to allow users to pause in handler | ||
await this.hooks.call('content:scroll', undefined, () => { | ||
return this.scrollToContent(); | ||
await this.hooks.call('content:scroll', visit, undefined, () => { | ||
return this.scrollToContent(visit); | ||
}); | ||
await this.hooks.call('page:view', { url: this.currentPageUrl, title: document.title }); | ||
await this.hooks.call('page:view', visit, { url: this.currentPageUrl, title: document.title }); | ||
}; |
@@ -56,3 +56,4 @@ import type Swup from '../Swup.js'; | ||
// Return true if all containers were replaced | ||
return replaced.length === containers.length; | ||
}; |
import type Swup from '../Swup.js'; | ||
import type { Visit } from './Visit.js'; | ||
@@ -7,6 +8,6 @@ /** | ||
*/ | ||
export const scrollToContent = function (this: Swup): boolean { | ||
export const scrollToContent = function (this: Swup, visit: Visit): boolean { | ||
const options: ScrollIntoViewOptions = { behavior: 'auto' }; | ||
const { target, reset } = this.visit.scroll; | ||
const scrollTarget = target ?? this.visit.to.hash; | ||
const { target, reset } = visit.scroll; | ||
const scrollTarget = target ?? visit.to.hash; | ||
@@ -18,2 +19,3 @@ let scrolled = false; | ||
'scroll:anchor', | ||
visit, | ||
{ hash: scrollTarget, options }, | ||
@@ -31,3 +33,3 @@ (visit, { hash, options }) => { | ||
if (reset && !scrolled) { | ||
scrolled = this.hooks.callSync('scroll:top', { options }, (visit, { options }) => { | ||
scrolled = this.hooks.callSync('scroll:top', visit, { options }, (visit, { options }) => { | ||
window.scrollTo({ top: 0, left: 0, ...options }); | ||
@@ -34,0 +36,0 @@ return true; |
@@ -5,23 +5,4 @@ import type Swup from '../Swup.js'; | ||
/** An object holding details about the current visit. */ | ||
export interface Visit { | ||
/** A unique ID to identify this visit */ | ||
id: number; | ||
/** The previous page, about to leave */ | ||
from: VisitFrom; | ||
/** The next page, about to enter */ | ||
to: VisitTo; | ||
/** The content containers, about to be replaced */ | ||
containers: Options['containers']; | ||
/** Information about animated page transitions */ | ||
animation: VisitAnimation; | ||
/** What triggered this visit */ | ||
trigger: VisitTrigger; | ||
/** Cache behavior for this visit */ | ||
cache: VisitCache; | ||
/** Browser history behavior on this visit */ | ||
history: VisitHistory; | ||
/** Scroll behavior on this visit */ | ||
scroll: VisitScroll; | ||
} | ||
/** See below for the class Visit {} definition */ | ||
// export interface Visit {} | ||
@@ -49,2 +30,4 @@ export interface VisitFrom { | ||
name?: string; | ||
/** Whether this animation uses the native browser ViewTransition API. Default: `false` */ | ||
native: boolean; | ||
/** Elements on which to add animation classes. Default: `html` element */ | ||
@@ -94,37 +77,93 @@ scope: 'html' | 'containers' | string[]; | ||
/** Create a new visit object. */ | ||
export function createVisit( | ||
this: Swup, | ||
{ to, from = this.currentPageUrl, hash, el, event }: VisitInitOptions | ||
): Visit { | ||
return { | ||
id: Math.random(), | ||
from: { url: from }, | ||
to: { url: to, hash }, | ||
containers: this.options.containers, | ||
animation: { | ||
/** @internal */ | ||
export const VisitState = { | ||
CREATED: 1, | ||
QUEUED: 2, | ||
STARTED: 3, | ||
LEAVING: 4, | ||
LOADED: 5, | ||
ENTERING: 6, | ||
COMPLETED: 7, | ||
ABORTED: 8, | ||
FAILED: 9 | ||
} as const; | ||
/** @internal */ | ||
export type VisitState = (typeof VisitState)[keyof typeof VisitState]; | ||
/** An object holding details about the current visit. */ | ||
export class Visit { | ||
/** A unique ID to identify this visit */ | ||
id: number; | ||
/** The current state of this visit @internal */ | ||
state: VisitState; | ||
/** The previous page, about to leave */ | ||
from: VisitFrom; | ||
/** The next page, about to enter */ | ||
to: VisitTo; | ||
/** The content containers, about to be replaced */ | ||
containers: Options['containers']; | ||
/** Information about animated page transitions */ | ||
animation: VisitAnimation; | ||
/** What triggered this visit */ | ||
trigger: VisitTrigger; | ||
/** Cache behavior for this visit */ | ||
cache: VisitCache; | ||
/** Browser history behavior on this visit */ | ||
history: VisitHistory; | ||
/** Scroll behavior on this visit */ | ||
scroll: VisitScroll; | ||
constructor(swup: Swup, options: VisitInitOptions) { | ||
const { to, from = swup.currentPageUrl, hash, el, event } = options; | ||
this.id = Math.random(); | ||
this.state = VisitState.CREATED; | ||
this.from = { url: from }; | ||
this.to = { url: to, hash }; | ||
this.containers = swup.options.containers; | ||
this.animation = { | ||
animate: true, | ||
wait: false, | ||
name: undefined, | ||
scope: this.options.animationScope, | ||
selector: this.options.animationSelector | ||
}, | ||
trigger: { | ||
el, | ||
event | ||
}, | ||
cache: { | ||
read: this.options.cache, | ||
write: this.options.cache | ||
}, | ||
history: { | ||
native: swup.options.native, | ||
scope: swup.options.animationScope, | ||
selector: swup.options.animationSelector | ||
}; | ||
this.trigger = { el, event }; | ||
this.cache = { | ||
read: swup.options.cache, | ||
write: swup.options.cache | ||
}; | ||
this.history = { | ||
action: 'push', | ||
popstate: false, | ||
direction: undefined | ||
}, | ||
scroll: { | ||
}; | ||
this.scroll = { | ||
reset: true, | ||
target: undefined | ||
}; | ||
} | ||
/** @internal */ | ||
advance(state: VisitState) { | ||
if (this.state < state) { | ||
this.state = state; | ||
} | ||
}; | ||
} | ||
/** @internal */ | ||
abort() { | ||
this.state = VisitState.ABORTED; | ||
} | ||
/** Is this visit done, i.e. completed, failed, or aborted? */ | ||
get done(): boolean { | ||
return this.state >= VisitState.COMPLETED; | ||
} | ||
} | ||
/** Create a new visit object. */ | ||
export function createVisit(this: Swup, options: VisitInitOptions): Visit { | ||
return new Visit(this, options); | ||
} |
@@ -24,3 +24,3 @@ import { type DelegateEvent } from 'delegate-it'; | ||
import { nextTick } from './utils.js'; | ||
import { type HistoryState } from './helpers/createHistoryRecord.js'; | ||
import { type HistoryState } from './helpers/history.js'; | ||
@@ -45,2 +45,4 @@ /** Options for customizing swup's behavior. */ | ||
linkToSelf: NavigationToSelfAction; | ||
/** Enable native animations using the View Transitions API. */ | ||
native: boolean; | ||
/** Plugins to register on startup. */ | ||
@@ -67,2 +69,3 @@ plugins: Plugin[]; | ||
linkToSelf: 'scroll', | ||
native: false, | ||
plugins: [], | ||
@@ -104,2 +107,4 @@ resolveUrl: (url) => url, | ||
protected navigating: boolean = false; | ||
/** Run anytime a visit ends */ | ||
protected onVisitEnd?: () => Promise<unknown>; | ||
@@ -192,2 +197,5 @@ /** Install a plugin */ | ||
// Sanitize/check native option | ||
this.options.native = this.options.native && !!document.startViewTransition; | ||
// Mount plugins | ||
@@ -205,5 +213,6 @@ this.options.plugins.forEach((plugin) => this.use(plugin)); | ||
// Trigger enable hook | ||
await this.hooks.call('enable', undefined, () => { | ||
// Add swup-enabled class to html tag | ||
document.documentElement.classList.add('swup-enabled'); | ||
await this.hooks.call('enable', undefined, undefined, () => { | ||
const html = document.documentElement; | ||
html.classList.add('swup-enabled'); | ||
html.classList.toggle('swup-native', this.options.native); | ||
}); | ||
@@ -227,5 +236,6 @@ } | ||
// trigger disable hook | ||
await this.hooks.call('disable', undefined, () => { | ||
// remove swup-enabled class from html tag | ||
document.documentElement.classList.remove('swup-enabled'); | ||
await this.hooks.call('disable', undefined, undefined, () => { | ||
const html = document.documentElement; | ||
html.classList.remove('swup-enabled'); | ||
html.classList.remove('swup-native'); | ||
}); | ||
@@ -275,7 +285,7 @@ | ||
this.visit = this.createVisit({ to: url, hash, el, event }); | ||
const visit = this.createVisit({ to: url, hash, el, event }); | ||
// Exit early if control key pressed | ||
if (event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) { | ||
this.hooks.call('link:newtab', { href }); | ||
this.hooks.callSync('link:newtab', visit, { href }); | ||
return; | ||
@@ -289,4 +299,4 @@ } | ||
this.hooks.callSync('link:click', { el, event }, () => { | ||
const from = this.visit.from.url ?? ''; | ||
this.hooks.callSync('link:click', visit, { el, event }, () => { | ||
const from = visit.from.url ?? ''; | ||
@@ -299,16 +309,14 @@ event.preventDefault(); | ||
// With hash: scroll to anchor | ||
this.hooks.callSync('link:anchor', { hash }, () => { | ||
this.hooks.callSync('link:anchor', visit, { hash }, () => { | ||
updateHistoryRecord(url + hash); | ||
this.scrollToContent(); | ||
this.scrollToContent(visit); | ||
}); | ||
} else { | ||
// Without hash: scroll to top or load/reload page | ||
this.hooks.callSync('link:self', undefined, () => { | ||
switch (this.options.linkToSelf) { | ||
case 'navigate': | ||
return this.performNavigation(); | ||
case 'scroll': | ||
default: | ||
updateHistoryRecord(url); | ||
return this.scrollToContent(); | ||
this.hooks.callSync('link:self', visit, undefined, () => { | ||
if (this.options.linkToSelf === 'navigate') { | ||
this.performNavigation(visit); | ||
} else { | ||
updateHistoryRecord(url); | ||
this.scrollToContent(visit); | ||
} | ||
@@ -326,3 +334,3 @@ }); | ||
// Finally, proceed with loading the page | ||
this.performNavigation(); | ||
this.performNavigation(visit); | ||
}); | ||
@@ -346,6 +354,6 @@ } | ||
this.visit = this.createVisit({ to: url, hash, event }); | ||
const visit = this.createVisit({ to: url, hash, event }); | ||
// Mark as history visit | ||
this.visit.history.popstate = true; | ||
visit.history.popstate = true; | ||
@@ -356,3 +364,3 @@ // Determine direction of history visit | ||
const direction = index - this.currentHistoryIndex > 0 ? 'forwards' : 'backwards'; | ||
this.visit.history.direction = direction; | ||
visit.history.direction = direction; | ||
this.currentHistoryIndex = index; | ||
@@ -362,19 +370,14 @@ } | ||
// Disable animation & scrolling for history visits | ||
this.visit.animation.animate = false; | ||
this.visit.scroll.reset = false; | ||
this.visit.scroll.target = false; | ||
visit.animation.animate = false; | ||
visit.scroll.reset = false; | ||
visit.scroll.target = false; | ||
// Animated history visit: re-enable animation & scroll reset | ||
if (this.options.animateHistoryBrowsing) { | ||
this.visit.animation.animate = true; | ||
this.visit.scroll.reset = true; | ||
visit.animation.animate = true; | ||
visit.scroll.reset = true; | ||
} | ||
// Does this even do anything? | ||
// if (!hash) { | ||
// event.preventDefault(); | ||
// } | ||
this.hooks.callSync('history:popstate', { event }, () => { | ||
this.performNavigation(); | ||
this.hooks.callSync('history:popstate', visit, { event }, () => { | ||
this.performNavigation(visit); | ||
}); | ||
@@ -381,0 +384,0 @@ } |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
678265
3306
21
92