From c0877999f8e315e5f1f240998ddc438e6c5aebe6 Mon Sep 17 00:00:00 2001 From: Jake Whiteley Date: Tue, 17 Sep 2024 18:05:09 +0100 Subject: [PATCH] 1.7.0 - better query string handling --- dist/taxi.esm.js | 2 +- dist/taxi.esm.js.map | 2 +- dist/taxi.js | 2 +- dist/taxi.js.map | 2 +- dist/taxi.modern.js | 2 +- dist/taxi.modern.js.map | 2 +- dist/taxi.umd.js | 2 +- dist/taxi.umd.js.map | 2 +- package.json | 2 +- src/Core.d.ts | 2 ++ src/Core.js | 6 +++++- src/helpers.d.ts | 3 ++- src/helpers.js | 3 ++- 13 files changed, 20 insertions(+), 12 deletions(-) diff --git a/dist/taxi.esm.js b/dist/taxi.esm.js index e4ca392..abbef35 100644 --- a/dist/taxi.esm.js +++ b/dist/taxi.esm.js @@ -1,2 +1,2 @@ -import t from"@unseenco/e";function e(){return e=Object.assign||function(t){for(var e=1;et.length)&&(e=t.length);for(var r=0,n=new Array(e);r=t.length?{done:!0}:{done:!1,value:t[i++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var i=new DOMParser;function o(t){var e=new URL(t,window.location.origin),r=e.hash.length?t.replace(e.hash,""):null;return{hasHash:e.hash.length>0,pathname:e.pathname,host:e.host,raw:t,href:r||e.href}}function a(t,e){t.parentNode.replaceChild(s(t,e),t)}function c(t,e){("HEAD"===t.parentNode.tagName?document.head:document.body).appendChild(s(t,e))}function s(t,e){for(var r=document.createElement(e),n=0;nt.length)&&(e=t.length);for(var r=0,n=new Array(e);r=t.length?{done:!0}:{done:!1,value:t[i++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var i=new DOMParser;function o(t){var e=new URL(t,window.location.origin),r=e.hash.length?t.replace(e.hash,""):null;return{hasHash:e.hash.length>0,pathname:e.pathname,host:e.host,search:e.search,raw:t,href:r||e.href}}function a(t,e){t.parentNode.replaceChild(s(t,e),t)}function c(t,e){("HEAD"===t.parentNode.tagName?document.head:document.body).appendChild(s(t,e))}function s(t,e){for(var r=document.createElement(e),n=0;n 0,\n\t\tpathname: details.pathname,\n\t\thost: details.host,\n\t\traw: url,\n\t\thref: normalized || details.href\n\t}\n}\n\n/**\n * Reloads a provided script/stylesheet by replacing with itself.\n *\n * @param {HTMLElement|HTMLScriptElement|HTMLStyleElement} node\n * @param {string} elementType - 'SCRIPT' or 'STYLE'\n */\nexport function reloadElement(node, elementType) {\n\tnode.parentNode.replaceChild(duplicateElement(node, elementType), node)\n}\n\n/**\n * Loads a provided script/stylesheet by appending a clone to the current document.\n *\n * @param {HTMLElement|HTMLStyleElement} node\n * @param {string} elementType - 'SCRIPT' or 'STYLE'\n */\nexport function appendElement(node, elementType) {\n\tconst target = node.parentNode.tagName === 'HEAD' ? document.head : document.body\n\ttarget.appendChild(duplicateElement(node, elementType))\n}\n\n/**\n * Creates a clone of a given HTMLElement or HTMLStyleElement\n *\n * @param {HTMLElement|HTMLStyleElement} node\n * @param {string} elementType - 'SCRIPT' or 'STYLE'\n * @return {HTMLElement|HTMLStyleElement}\n */\nexport function duplicateElement(node, elementType) {\n\tconst replacement = document.createElement(elementType)\n\n\tfor (let k = 0; k < node.attributes.length; k++) {\n\t\tconst attr = node.attributes[k]\n\t\treplacement.setAttribute(attr.nodeName, attr.nodeValue)\n\t}\n\n\t// Inline Script or Style\n\tif (node.innerHTML) {\n\t\treplacement.innerHTML = node.innerHTML\n\t}\n\n\treturn replacement\n}\n","export default class Transition {\n\t/**\n\t * @param {{wrapper: HTMLElement}} props\n\t */\n\tconstructor({ wrapper }) {\n\t\tthis.wrapper = wrapper\n\t}\n\n\t/**\n\t * @param {{ from: HTMLElement|Element, trigger: string|HTMLElement|false }} props\n\t * @return {Promise}\n\t */\n\tleave(props) {\n\t\treturn new Promise((resolve) => {\n\t\t\tthis.onLeave({ ...props, done: resolve })\n\t\t})\n\t}\n\n\t/**\n\t * @param {{ to: HTMLElement|Element, trigger: string|HTMLElement|false }} props\n\t * @return {Promise}\n\t */\n\tenter(props) {\n\t\treturn new Promise((resolve) => {\n\t\t\tthis.onEnter({ ...props, done: resolve })\n\t\t})\n\t}\n\n\t/**\n\t * Handle the transition leaving the previous page.\n\t * @param {{from: HTMLElement|Element, trigger: string|HTMLElement|false, done: function}} props\n\t */\n\tonLeave({ from, trigger, done }) {\n\t\tdone()\n\t}\n\n\t/**\n\t * Handle the transition entering the next page.\n\t * @param {{to: HTMLElement|Element, trigger: string|HTMLElement|false, done: function}} props\n\t */\n\tonEnter({ to, trigger, done }) {\n\t\tdone()\n\t}\n}\n","import Transition from \"./Transition\"\n\nexport default class Renderer {\n\t/**\n\t * @param {{content: HTMLElement|Element, page: Document|Node, title: string, wrapper: Element}} props\n\t */\n\tconstructor({ content, page, title, wrapper }) {\n\t\tthis._contentString = content.outerHTML\n\t\tthis._DOM = null\n\t\tthis.page = page\n\t\tthis.title = title\n\t\tthis.wrapper = wrapper\n\t\tthis.content = this.wrapper.lastElementChild\n\t}\n\n\tonEnter() {\n\n\t}\n\n\tonEnterCompleted() {\n\n\t}\n\n\tonLeave() {\n\n\t}\n\n\tonLeaveCompleted() {\n\n\t}\n\n\tinitialLoad() {\n\t\tthis.onEnter()\n\t\tthis.onEnterCompleted()\n\t}\n\n\tupdate() {\n\t\tdocument.title = this.title\n\t\tthis.wrapper.appendChild(this._DOM.firstElementChild)\n\t\tthis.content = this.wrapper.lastElementChild\n\t\tthis._DOM = null\n\t}\n\n\tcreateDom() {\n\t\tif (!this._DOM) {\n\t\t\tthis._DOM = document.createElement('div')\n\t\t\tthis._DOM.innerHTML = this._contentString\n\t\t}\n\t}\n\n\tremove() {\n\t\tthis.wrapper.firstElementChild.remove()\n\t}\n\n\t/**\n\t * Called when transitioning into the current page.\n\t * @param {Transition} transition\n\t * @param {string|HTMLElement|false} trigger\n\t * @return {Promise}\n\t */\n\tenter(transition, trigger) {\n\t\treturn new Promise((resolve) => {\n\t\t\tthis.onEnter()\n\n\t\t\ttransition.enter({ trigger, to: this.content })\n\t\t\t\t.then(() => {\n\t\t\t\t\tthis.onEnterCompleted()\n\t\t\t\t\tresolve()\n\t\t\t\t})\n\t\t})\n\t}\n\n\t/**\n\t * Called when transitioning away from the current page.\n\t * @param {Transition} transition\n\t * @param {string|HTMLElement|false} trigger\n\t * @param {boolean} removeOldContent\n\t * @return {Promise}\n\t */\n\tleave(transition, trigger, removeOldContent) {\n\t\treturn new Promise((resolve) => {\n\t\t\tthis.onLeave()\n\n\t\t\ttransition.leave({ trigger, from: this.content })\n\t\t\t\t.then(() => {\n\t\t\t\t\tif (removeOldContent) {\n\t\t\t\t\t\tthis.remove()\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.onLeaveCompleted()\n\t\t\t\t\tresolve()\n\t\t\t\t})\n\t\t})\n\t}\n}\n","export default class RouteStore {\n\t/**\n\t * @type {Map>}\n\t */\n\tdata = new Map()\n\n\t/**\n\t * @type {Map}\n\t */\n\tregexCache = new Map()\n\n\t/**\n\t *\n\t * @param {string} fromPattern\n\t * @param {string} toPattern\n\t * @param {string} transition\n\t */\n\tadd(fromPattern, toPattern, transition) {\n\t\tif (!this.data.has(fromPattern)) {\n\t\t\tthis.data.set(fromPattern, new Map())\n\t\t\tthis.regexCache.set(fromPattern, new RegExp(`^${fromPattern}$`))\n\t\t}\n\n\t\tthis.data.get(fromPattern).set(toPattern, transition)\n\t\tthis.regexCache.set(toPattern, new RegExp(`^${toPattern}$`))\n\t}\n\n\t/**\n\t *\n\t * @param {{ raw: string, href: string, hasHash: boolean, pathname: string }} currentUrl\n\t * @param {{ raw: string, href: string, hasHash: boolean, pathname: string }} nextUrl\n\t * @return {string|null}\n\t */\n\tfindMatch(currentUrl, nextUrl) {\n\t\t// Loop through all from patterns\n\t\tfor (const [fromPattern, potentialMatches] of this.data) {\n\t\t\t// If we have a match\n\t\t\tif (currentUrl.pathname.match(this.regexCache.get(fromPattern))) {\n\t\t\t\t// loop through all associated to patterns\n\t\t\t\tfor (const [toPattern, transition] of potentialMatches) {\n\t\t\t\t\t// If we find a match, return it\n\t\t\t\t\tif (nextUrl.pathname.match(this.regexCache.get(toPattern))) {\n\t\t\t\t\t\treturn transition\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\treturn null\n\t}\n}\n","import E from '@unseenco/e'\nimport { appendElement, parseDom, processUrl, reloadElement } from './helpers'\nimport Transition from './Transition'\nimport Renderer from './Renderer'\nimport RouteStore from './RouteStore'\n\nconst IN_PROGRESS = 'A transition is currently in progress'\n\n/**\n * @typedef CacheEntry\n * @type {object}\n * @property {typeof Renderer|Renderer} renderer\n * @property {Document|Node} page\n * @property {array} scripts\n * @property {HTMLLinkElement[]} styles\n * @property {string} finalUrl\n * @property {boolean} skipCache\n * @property {string} title\n * @property {HTMLElement|Element} content\n */\n\nexport default class Core {\n\tisTransitioning = false\n\n\t/**\n\t * @type {CacheEntry|null}\n\t */\n\tcurrentCacheEntry = null\n\n\t/**\n\t * @type {Map}\n\t */\n\tcache = new Map()\n\n\t/**\n\t * @private\n\t * @type {Map}\n\t */\n\tactivePromises = new Map()\n\n\t/**\n\t * @param {{\n\t * \t\tlinks?: string,\n\t * \t\tremoveOldContent?: boolean,\n\t * \t\tallowInterruption?: boolean,\n\t * \t\tbypassCache?: boolean,\n\t * \t\tenablePrefetch?: boolean,\n\t * \t\trenderers?: Object.,\n\t * \t\ttransitions?: Object.,\n\t * \t\treloadJsFilter?: boolean|function(HTMLElement): boolean,\n\t * \t\treloadCssFilter?: boolean|function(HTMLLinkElement): boolean\n\t * }} parameters\n\t */\n\tconstructor(parameters = {}) {\n\t\tconst {\n\t\t\tlinks = 'a:not([target]):not([href^=\\\\#]):not([data-taxi-ignore])',\n\t\t\tremoveOldContent = true,\n\t\t\tallowInterruption = false,\n\t\t\tbypassCache = false,\n\t\t\tenablePrefetch = true,\n\t\t\trenderers = {\n\t\t\t\tdefault: Renderer\n\t\t\t},\n\t\t\ttransitions = {\n\t\t\t\tdefault: Transition\n\t\t\t},\n\t\t\treloadJsFilter = (element) => element.dataset.taxiReload !== undefined,\n\t\t\treloadCssFilter = (element) => true //element.dataset.taxiReload !== undefined\n\t\t} = parameters\n\n\t\tthis.renderers = renderers\n\t\tthis.transitions = transitions\n\t\tthis.defaultRenderer = this.renderers.default || Renderer\n\t\tthis.defaultTransition = this.transitions.default || Transition\n\t\tthis.wrapper = document.querySelector('[data-taxi]')\n\t\tthis.reloadJsFilter = reloadJsFilter\n\t\tthis.reloadCssFilter = reloadCssFilter\n\t\tthis.removeOldContent = removeOldContent\n\t\tthis.allowInterruption = allowInterruption\n\t\tthis.bypassCache = bypassCache\n\t\tthis.enablePrefetch = enablePrefetch\n\t\tthis.cache = new Map()\n\t\tthis.isPopping = false\n\n\t\t// Add delegated link events\n\t\tthis.attachEvents(links)\n\n\t\tthis.currentLocation = processUrl(window.location.href)\n\n\t\t// as this is the initial page load, prime this page into the cache\n\t\tthis.cache.set(this.currentLocation.href, this.createCacheEntry(document.cloneNode(true), window.location.href))\n\n\t\t// fire the current Renderer enter methods\n\t\tthis.currentCacheEntry = this.cache.get(this.currentLocation.href)\n\t\tthis.currentCacheEntry.renderer.initialLoad()\n\t}\n\n\t/**\n\t * @param {string} renderer\n\t */\n\tsetDefaultRenderer(renderer) {\n\t\tthis.defaultRenderer = this.renderers[renderer]\n\t}\n\n\t/**\n\t * @param {string} transition\n\t */\n\tsetDefaultTransition(transition) {\n\t\tthis.defaultTransition = this.transitions[transition]\n\t}\n\n\t/**\n\t * Registers a route into the RouteStore\n\t *\n\t * @param {string} fromPattern\n\t * @param {string} toPattern\n\t * @param {string} transition\n\t */\n\taddRoute(fromPattern, toPattern, transition) {\n\t\tif (!this.router) {\n\t\t\tthis.router = new RouteStore()\n\t\t}\n\n\t\tthis.router.add(fromPattern, toPattern, transition)\n\t}\n\n\t/**\n\t * Prime the cache for a given URL\n\t *\n\t * @param {string} url\n\t * @param {boolean} [preloadAssets]\n\t * @return {Promise}\n\t */\n\tpreload(url, preloadAssets = false) {\n\t\t// convert relative URLs to absolute\n\t\turl = processUrl(url).href\n\n\t\tif (!this.cache.has(url)) {\n\t\t\treturn this.fetch(url, false)\n\t\t\t\t.then(async (response) => {\n\t\t\t\t\tthis.cache.set(url, this.createCacheEntry(response.html, response.url))\n\n\t\t\t\t\tif (preloadAssets) {\n\t\t\t\t\t\tthis.cache.get(url).renderer.createDom()\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\t.catch(err => console.warn(err))\n\t\t}\n\n\t\treturn Promise.resolve()\n\t}\n\n\t/**\n\t * Updates the HTML cache for a given URL.\n\t * If no URL is passed, then cache for the current page is updated.\n\t * Useful when adding/removing content via AJAX such as a search page or infinite loader.\n\t *\n\t * @param {string} [url]\n\t */\n\tupdateCache(url) {\n\t\tconst key = processUrl(url || window.location.href).href\n\n\t\tif (this.cache.has(key)) {\n\t\t\tthis.cache.delete(key)\n\t\t}\n\n\t\tthis.cache.set(key, this.createCacheEntry(document.cloneNode(true), key))\n\t}\n\n\t/**\n\t * Clears the cache for a given URL.\n\t * If no URL is passed, then cache for the current page is cleared.\n\t *\n\t * @param {string} [url]\n\t */\n\tclearCache(url) {\n\t\tconst key = processUrl(url || window.location.href).href\n\n\t\tif (this.cache.has(key)) {\n\t\t\tthis.cache.delete(key)\n\t\t}\n\t}\n\n\t/**\n\t * @param {string} url\n\t * @param {string|false} [transition]\n\t * @param {string|false|HTMLElement} [trigger]\n\t * @return {Promise}\n\t */\n\tnavigateTo(url, transition = false, trigger = false) {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\t// Don't allow multiple navigations to occur at once\n\t\t\tif (!this.allowInterruption && this.isTransitioning) {\n\t\t\t\treject(new Error(IN_PROGRESS))\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tthis.isTransitioning = true\n\t\t\tthis.isPopping = true\n\t\t\tthis.targetLocation = processUrl(url)\n\t\t\tthis.popTarget = window.location.href\n\n\t\t\tconst TransitionClass = new (this.chooseTransition(transition))({ wrapper: this.wrapper })\n\n\t\t\tlet navigationPromise\n\n\t\t\tif (this.bypassCache || !this.cache.has(this.targetLocation.href) || this.cache.get(this.targetLocation.href).skipCache) {\n\t\t\t\tconst fetched = this.fetch(this.targetLocation.href)\n\t\t\t\t\t.then((response) => {\n\t\t\t\t\t\tthis.cache.set(this.targetLocation.href, this.createCacheEntry(response.html, response.url))\n\t\t\t\t\t\tthis.cache.get(this.targetLocation.href).renderer.createDom()\n\t\t\t\t\t})\n\t\t\t\t\t.catch(err => {\n\t\t\t\t\t\t// we encountered a 4** or 5** error, redirect to the requested URL\n\t\t\t\t\t\twindow.location.href = url\n\t\t\t\t\t})\n\n\t\t\t\tnavigationPromise = this.beforeFetch(this.targetLocation, TransitionClass, trigger)\n\t\t\t\t\t.then(async () => {\n\t\t\t\t\t\treturn fetched.then(async () => {\n\t\t\t\t\t\t\treturn await this.afterFetch(this.targetLocation, TransitionClass, this.cache.get(this.targetLocation.href), trigger)\n\t\t\t\t\t\t})\n\t\t\t\t\t})\n\t\t\t} else {\n\t\t\t\tthis.cache.get(this.targetLocation.href).renderer.createDom()\n\n\t\t\t\tnavigationPromise = this.beforeFetch(this.targetLocation, TransitionClass, trigger)\n\t\t\t\t\t.then(async () => {\n\t\t\t\t\t\treturn await this.afterFetch(this.targetLocation, TransitionClass, this.cache.get(this.targetLocation.href), trigger)\n\t\t\t\t\t})\n\t\t\t}\n\n\t\t\tnavigationPromise.then(() => {\n\t\t\t\tresolve()\n\t\t\t})\n\t\t})\n\t}\n\n\t/**\n\t * Add an event listener.\n\t * @param {string} event\n\t * @param {any} callback\n\t */\n\ton(event, callback) {\n\t\tE.on(event, callback)\n\t}\n\n\t/**\n\t * Remove an event listener.\n\t * @param {string} event\n\t * @param {any} [callback]\n\t */\n\toff(event, callback) {\n\t\tE.off(event, callback)\n\t}\n\n\t/**\n\t * @private\n\t * @param {{ raw: string, href: string, hasHash: boolean, pathname: string }} url\n\t * @param {Transition} TransitionClass\n\t * @param {string|HTMLElement|false} trigger\n\t * @return {Promise}\n\t */\n\tbeforeFetch(url, TransitionClass, trigger) {\n\t\tE.emit('NAVIGATE_OUT', {\n\t\t\tfrom: this.currentCacheEntry,\n\t\t\ttrigger\n\t\t})\n\n\t\treturn new Promise((resolve) => {\n\t\t\tthis.currentCacheEntry.renderer.leave(TransitionClass, trigger, this.removeOldContent)\n\t\t\t\t.then(() => {\n\t\t\t\t\tif (trigger !== 'popstate') {\n\t\t\t\t\t\twindow.history.pushState({}, '', url.raw)\n\t\t\t\t\t}\n\n\t\t\t\t\tresolve()\n\t\t\t\t})\n\t\t})\n\t}\n\n\t/**\n\t * @private\n\t * @param {{ raw: string, href: string, host: string, hasHash: boolean, pathname: string }} url\n\t * @param {Transition} TransitionClass\n\t * @param {CacheEntry} entry\n\t * @param {string|HTMLElement|false} trigger\n\t * @return {Promise}\n\t */\n\tafterFetch(url, TransitionClass, entry, trigger) {\n\t\tthis.currentLocation = url\n\t\tthis.popTarget = this.currentLocation.href\n\n\t\treturn new Promise((resolve) => {\n\t\t\tentry.renderer.update()\n\n\t\t\tE.emit('NAVIGATE_IN', {\n\t\t\t\tfrom: this.currentCacheEntry,\n\t\t\t\tto: entry,\n\t\t\t\ttrigger\n\t\t\t})\n\n\t\t\tif (this.reloadJsFilter) {\n\t\t\t\tthis.loadScripts(entry.scripts)\n\t\t\t}\n\n\t\t\tif (this.reloadCssFilter) {\n\t\t\t\tthis.loadStyles(entry.styles)\n\t\t\t}\n\n\t\t\t// If the fetched url had a redirect chain, then replace the history to reflect the final resolved URL\n\t\t\tif (trigger !== 'popstate' && url.href !== entry.finalUrl) {\n\t\t\t\twindow.history.replaceState({}, '', entry.finalUrl)\n\t\t\t}\n\n\t\t\tentry.renderer.enter(TransitionClass, trigger)\n\t\t\t\t.then(() => {\n\t\t\t\t\tE.emit('NAVIGATE_END', {\n\t\t\t\t\t\tfrom: this.currentCacheEntry,\n\t\t\t\t\t\tto: entry,\n\t\t\t\t\t\ttrigger\n\t\t\t\t\t})\n\n\t\t\t\t\tthis.currentCacheEntry = entry\n\t\t\t\t\tthis.isTransitioning = false\n\t\t\t\t\tthis.isPopping = false\n\t\t\t\t\tresolve()\n\t\t\t\t})\n\t\t})\n\t}\n\n\t/**\n\t * Load up scripts from the target page if needed\n\t *\n\t * @param {HTMLElement[]} cachedScripts\n\t */\n\tloadScripts(cachedScripts) {\n\t\tconst newScripts = [...cachedScripts]\n\t\tconst currentScripts = Array.from(document.querySelectorAll('script')).filter(this.reloadJsFilter)\n\n\t\t// loop through all new scripts\n\t\tfor (let i = 0; i < currentScripts.length; i++) {\n\t\t\tfor (let n = 0; n < newScripts.length; n++) {\n\t\t\t\tif (currentScripts[i].outerHTML === newScripts[n].outerHTML) {\n\t\t\t\t\treloadElement(currentScripts[i], 'SCRIPT')\n\t\t\t\t\tnewScripts.splice(n, 1)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tfor (const script of newScripts) {\n\t\t\tappendElement(script, 'SCRIPT')\n\t\t}\n\t}\n\n\t/**\n\t * Load up styles from the target page if needed\n\t *\n\t * @param {Array} cachedStyles\n\t */\n\tloadStyles(cachedStyles) {\n\t\tconst currentStyles = Array.from(document.querySelectorAll('link[rel=\"stylesheet\"]')).filter(this.reloadCssFilter)\n\t\tconst currentInlineStyles = Array.from(document.querySelectorAll('style')).filter(this.reloadCssFilter)\n\n\t\tconst newInlineStyles = cachedStyles.filter(el => {\n\t\t\t// no el.href, assume it's an inline style\n\t\t\tif (!el.href) {\n\t\t\t\treturn true\n\t\t\t} else if (!currentStyles.find((link) => link.href === el.href)) {\n\t\t\t\tdocument.body.append(el)\n\t\t\t\treturn false\n\t\t\t}\n\t\t})\n\n\t\t// loop through all new inline styles\n\t\tfor (let i = 0; i < currentInlineStyles.length; i++) {\n\t\t\tfor (let n = 0; n < newInlineStyles.length; n++) {\n\t\t\t\tif (currentInlineStyles[i].outerHTML === newInlineStyles[n].outerHTML) {\n\t\t\t\t\treloadElement(currentInlineStyles[i], 'STYLE')\n\t\t\t\t\tnewInlineStyles.splice(n, 1)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tfor (const style of newInlineStyles) {\n\t\t\tappendElement(style, 'STYLE')\n\t\t}\n\t}\n\n\t/**\n\t * @private\n\t * @param {string} links\n\t */\n\tattachEvents(links) {\n\t\tE.delegate('click', links, this.onClick)\n\t\tE.on('popstate', window, this.onPopstate)\n\n\t\tif (this.enablePrefetch) {\n\t\t\tE.delegate('mouseenter focus', links, this.onPrefetch)\n\t\t}\n\t}\n\n\t/**\n\t * @private\n\t * @param {MouseEvent} e\n\t */\n\tonClick = (e) => {\n\t\tif (!(e.metaKey || e.ctrlKey)) {\n\t\t\tconst target = processUrl(e.currentTarget.href)\n\t\t\tthis.currentLocation = processUrl(window.location.href)\n\n\t\t\tif (this.currentLocation.host !== target.host) {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// the target is a new URL, or is removing the hash from the current URL\n\t\t\tif (this.currentLocation.href !== target.href || (this.currentLocation.hasHash && !target.hasHash)) {\n\t\t\t\te.preventDefault()\n\t\t\t\t// noinspection JSIgnoredPromiseFromCall\n\t\t\t\tthis.navigateTo(target.raw, e.currentTarget.dataset.transition || false, e.currentTarget).catch(err => console.warn(err))\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// a click to the current URL was detected\n\t\t\tif (!this.currentLocation.hasHash && !target.hasHash) {\n\t\t\t\te.preventDefault()\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * @private\n\t * @return {void|boolean}\n\t */\n\tonPopstate = () => {\n\t\t// don't trigger for on-page anchors\n\t\tif (window.location.pathname === this.currentLocation.pathname && !this.isPopping) {\n\t\t\treturn false\n\t\t}\n\n\t\tif (!this.allowInterruption && (this.isTransitioning || this.isPopping)) {\n\t\t\t// overwrite history state with current page if currently navigating\n\t\t\twindow.history.pushState({}, '', this.popTarget)\n\t\t\tconsole.warn(IN_PROGRESS)\n\t\t\treturn false\n\t\t}\n\n\t\tif (!this.isPopping) {\n\t\t\tthis.popTarget = window.location.href\n\t\t}\n\n\t\tthis.isPopping = true\n\n\t\t// noinspection JSIgnoredPromiseFromCall\n\t\tthis.navigateTo(window.location.href, false, 'popstate')\n\t}\n\n\t/**\n\t * @private\n\t * @param {MouseEvent} e\n\t */\n\tonPrefetch = (e) => {\n\t\tconst target = processUrl(e.currentTarget.href)\n\n\t\tif (this.currentLocation.host !== target.host) {\n\t\t\treturn\n\t\t}\n\n\t\tthis.preload(e.currentTarget.href, false)\n\t}\n\n\t/**\n\t * @private\n\t * @param {string} url\n\t * @param {boolean} [runFallback]\n\t * @return {Promise<{html: Document, url: string}>}\n\t */\n\tfetch(url, runFallback = true) {\n\t\t// If Taxi is currently performing a fetch for the given URL, return that instead of starting a new request\n\t\tif (this.activePromises.has(url)) {\n\t\t\treturn this.activePromises.get(url)\n\t\t}\n\n\t\tconst request = new Promise((resolve, reject) => {\n\t\t\tlet resolvedUrl\n\n\t\t\tfetch(url, {\n\t\t\t\tmode: 'same-origin',\n\t\t\t\tmethod: 'GET',\n\t\t\t\theaders: { 'X-Requested-With': 'Taxi' },\n\t\t\t\tcredentials: 'same-origin'\n\t\t\t})\n\t\t\t\t.then((response) => {\n\t\t\t\t\tif (!response.ok) {\n\t\t\t\t\t\treject('Taxi encountered a non 2xx HTTP status code')\n\n\t\t\t\t\t\tif (runFallback) {\n\t\t\t\t\t\t\twindow.location.href = url\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tresolvedUrl = response.url\n\n\t\t\t\t\treturn response.text()\n\t\t\t\t})\n\t\t\t\t.then((htmlString) => {\n\t\t\t\t\tresolve({ html: parseDom(htmlString), url: resolvedUrl })\n\t\t\t\t})\n\t\t\t\t.catch((err) => {\n\t\t\t\t\treject(err)\n\n\t\t\t\t\tif (runFallback) {\n\t\t\t\t\t\twindow.location.href = url\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\t.finally(() => {\n\t\t\t\t\tthis.activePromises.delete(url)\n\t\t\t\t})\n\t\t})\n\n\t\tthis.activePromises.set(url, request)\n\n\t\treturn request\n\t}\n\n\t/**\n\t * @private\n\t * @param {string|false} transition\n\t * @return {Transition|function}\n\t */\n\tchooseTransition(transition) {\n\t\tif (transition) {\n\t\t\treturn this.transitions[transition]\n\t\t}\n\n\t\tconst routeTransition = this.router?.findMatch(this.currentLocation, this.targetLocation)\n\n\t\tif (routeTransition) {\n\t\t\treturn this.transitions[routeTransition]\n\t\t}\n\n\t\treturn this.defaultTransition\n\t}\n\n\t/**\n\t * @private\n\t * @param {Document|Node} page\n\t * @param {string} url\n\t * @return {CacheEntry}\n\t */\n\tcreateCacheEntry(page, url) {\n\t\tconst content = page.querySelector('[data-taxi-view]')\n\t\tconst Renderer = content.dataset.taxiView.length ? this.renderers[content.dataset.taxiView] : this.defaultRenderer\n\n\t\tif (!Renderer) {\n\t\t\tconsole.warn(`The Renderer \"${content.dataset.taxiView}\" was set in the data-taxi-view of the requested page, but not registered in Taxi.`)\n\t\t}\n\n\t\treturn {\n\t\t\tpage,\n\t\t\tcontent,\n\t\t\tfinalUrl: url,\n\t\t\tskipCache: content.hasAttribute('data-taxi-nocache'),\n\t\t\tscripts: this.reloadJsFilter ? Array.from(page.querySelectorAll('script')).filter(this.reloadJsFilter) : [],\n\t\t\tstyles: this.reloadCssFilter ? Array.from(page.querySelectorAll('link[rel=\"stylesheet\"], style')).filter(this.reloadCssFilter) : [],\n\t\t\ttitle: page.title,\n\t\t\trenderer: new Renderer({\n\t\t\t\twrapper: this.wrapper,\n\t\t\t\ttitle: page.title,\n\t\t\t\tcontent,\n\t\t\t\tpage\n\t\t\t})\n\t\t}\n\t}\n}\n"],"names":["parser","DOMParser","processUrl","url","details","URL","window","location","origin","normalized","hash","length","replace","hasHash","pathname","host","raw","href","reloadElement","node","elementType","parentNode","replaceChild","duplicateElement","appendElement","tagName","document","head","body","appendChild","replacement","createElement","k","attributes","attr","setAttribute","nodeName","nodeValue","innerHTML","Transition","this","wrapper","leave","props","Promise","resolve","_this","onLeave","done","enter","_this2","onEnter","Renderer","page","title","_contentString","content","outerHTML","_DOM","lastElementChild","onEnterCompleted","onLeaveCompleted","initialLoad","update","firstElementChild","createDom","remove","transition","trigger","to","then","removeOldContent","from","RouteStore","data","Map","regexCache","add","fromPattern","toPattern","has","set","RegExp","get","findMatch","currentUrl","nextUrl","potentialMatches","match","IN_PROGRESS","Core","parameters","isTransitioning","currentCacheEntry","cache","activePromises","onClick","e","metaKey","ctrlKey","target","currentTarget","currentLocation","preventDefault","navigateTo","dataset","err","console","warn","onPopstate","isPopping","allowInterruption","popTarget","history","pushState","onPrefetch","preload","links","bypassCache","enablePrefetch","renderers","transitions","default","reloadJsFilter","element","undefined","taxiReload","reloadCssFilter","defaultRenderer","defaultTransition","querySelector","attachEvents","createCacheEntry","cloneNode","renderer","setDefaultRenderer","setDefaultTransition","addRoute","router","preloadAssets","fetch","response","html","updateCache","key","clearCache","reject","_this3","targetLocation","navigationPromise","TransitionClass","chooseTransition","skipCache","fetched","beforeFetch","afterFetch","Error","on","event","callback","E","off","emit","_this4","entry","_this5","loadScripts","scripts","loadStyles","styles","finalUrl","replaceState","cachedScripts","newScripts","currentScripts","Array","querySelectorAll","filter","i","n","splice","cachedStyles","currentStyles","currentInlineStyles","newInlineStyles","el","find","link","append","delegate","runFallback","request","resolvedUrl","mode","method","headers","credentials","ok","text","htmlString","parseFromString","_this6","routeTransition","_this$router","taxiView","hasAttribute"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"taxi.esm.js","sources":["../src/helpers.js","../src/Transition.js","../src/Renderer.js","../src/RouteStore.js","../src/Core.js"],"sourcesContent":["const parser = new DOMParser()\n\n/**\n * Parse a HTML string into a proper Document.\n *\n * @param {string|Document} html\n * @return {Document|*}\n */\nexport function parseDom(html) {\n\treturn typeof html === 'string' ? parser.parseFromString(html, 'text/html') : html\n}\n\n/**\n * Extract details from a given URL string. Assumed to be on the current TLD.\n *\n * @param {string} url\n * @return {{raw: string, href: string, host: string, search: string, hasHash: boolean, pathname: string}}\n */\nexport function processUrl(url) {\n\tconst details = new URL(url, window.location.origin)\n\tconst normalized = details.hash.length ? url.replace(details.hash, '') : null\n\n\treturn {\n\t\thasHash: details.hash.length > 0,\n\t\tpathname: details.pathname,\n\t\thost: details.host,\n\t\tsearch: details.search,\n\t\traw: url,\n\t\thref: normalized || details.href\n\t}\n}\n\n/**\n * Reloads a provided script/stylesheet by replacing with itself.\n *\n * @param {HTMLElement|HTMLScriptElement|HTMLStyleElement} node\n * @param {string} elementType - 'SCRIPT' or 'STYLE'\n */\nexport function reloadElement(node, elementType) {\n\tnode.parentNode.replaceChild(duplicateElement(node, elementType), node)\n}\n\n/**\n * Loads a provided script/stylesheet by appending a clone to the current document.\n *\n * @param {HTMLElement|HTMLStyleElement} node\n * @param {string} elementType - 'SCRIPT' or 'STYLE'\n */\nexport function appendElement(node, elementType) {\n\tconst target = node.parentNode.tagName === 'HEAD' ? document.head : document.body\n\ttarget.appendChild(duplicateElement(node, elementType))\n}\n\n/**\n * Creates a clone of a given HTMLElement or HTMLStyleElement\n *\n * @param {HTMLElement|HTMLStyleElement} node\n * @param {string} elementType - 'SCRIPT' or 'STYLE'\n * @return {HTMLElement|HTMLStyleElement}\n */\nexport function duplicateElement(node, elementType) {\n\tconst replacement = document.createElement(elementType)\n\n\tfor (let k = 0; k < node.attributes.length; k++) {\n\t\tconst attr = node.attributes[k]\n\t\treplacement.setAttribute(attr.nodeName, attr.nodeValue)\n\t}\n\n\t// Inline Script or Style\n\tif (node.innerHTML) {\n\t\treplacement.innerHTML = node.innerHTML\n\t}\n\n\treturn replacement\n}\n","export default class Transition {\n\t/**\n\t * @param {{wrapper: HTMLElement}} props\n\t */\n\tconstructor({ wrapper }) {\n\t\tthis.wrapper = wrapper\n\t}\n\n\t/**\n\t * @param {{ from: HTMLElement|Element, trigger: string|HTMLElement|false }} props\n\t * @return {Promise}\n\t */\n\tleave(props) {\n\t\treturn new Promise((resolve) => {\n\t\t\tthis.onLeave({ ...props, done: resolve })\n\t\t})\n\t}\n\n\t/**\n\t * @param {{ to: HTMLElement|Element, trigger: string|HTMLElement|false }} props\n\t * @return {Promise}\n\t */\n\tenter(props) {\n\t\treturn new Promise((resolve) => {\n\t\t\tthis.onEnter({ ...props, done: resolve })\n\t\t})\n\t}\n\n\t/**\n\t * Handle the transition leaving the previous page.\n\t * @param {{from: HTMLElement|Element, trigger: string|HTMLElement|false, done: function}} props\n\t */\n\tonLeave({ from, trigger, done }) {\n\t\tdone()\n\t}\n\n\t/**\n\t * Handle the transition entering the next page.\n\t * @param {{to: HTMLElement|Element, trigger: string|HTMLElement|false, done: function}} props\n\t */\n\tonEnter({ to, trigger, done }) {\n\t\tdone()\n\t}\n}\n","import Transition from \"./Transition\"\n\nexport default class Renderer {\n\t/**\n\t * @param {{content: HTMLElement|Element, page: Document|Node, title: string, wrapper: Element}} props\n\t */\n\tconstructor({ content, page, title, wrapper }) {\n\t\tthis._contentString = content.outerHTML\n\t\tthis._DOM = null\n\t\tthis.page = page\n\t\tthis.title = title\n\t\tthis.wrapper = wrapper\n\t\tthis.content = this.wrapper.lastElementChild\n\t}\n\n\tonEnter() {\n\n\t}\n\n\tonEnterCompleted() {\n\n\t}\n\n\tonLeave() {\n\n\t}\n\n\tonLeaveCompleted() {\n\n\t}\n\n\tinitialLoad() {\n\t\tthis.onEnter()\n\t\tthis.onEnterCompleted()\n\t}\n\n\tupdate() {\n\t\tdocument.title = this.title\n\t\tthis.wrapper.appendChild(this._DOM.firstElementChild)\n\t\tthis.content = this.wrapper.lastElementChild\n\t\tthis._DOM = null\n\t}\n\n\tcreateDom() {\n\t\tif (!this._DOM) {\n\t\t\tthis._DOM = document.createElement('div')\n\t\t\tthis._DOM.innerHTML = this._contentString\n\t\t}\n\t}\n\n\tremove() {\n\t\tthis.wrapper.firstElementChild.remove()\n\t}\n\n\t/**\n\t * Called when transitioning into the current page.\n\t * @param {Transition} transition\n\t * @param {string|HTMLElement|false} trigger\n\t * @return {Promise}\n\t */\n\tenter(transition, trigger) {\n\t\treturn new Promise((resolve) => {\n\t\t\tthis.onEnter()\n\n\t\t\ttransition.enter({ trigger, to: this.content })\n\t\t\t\t.then(() => {\n\t\t\t\t\tthis.onEnterCompleted()\n\t\t\t\t\tresolve()\n\t\t\t\t})\n\t\t})\n\t}\n\n\t/**\n\t * Called when transitioning away from the current page.\n\t * @param {Transition} transition\n\t * @param {string|HTMLElement|false} trigger\n\t * @param {boolean} removeOldContent\n\t * @return {Promise}\n\t */\n\tleave(transition, trigger, removeOldContent) {\n\t\treturn new Promise((resolve) => {\n\t\t\tthis.onLeave()\n\n\t\t\ttransition.leave({ trigger, from: this.content })\n\t\t\t\t.then(() => {\n\t\t\t\t\tif (removeOldContent) {\n\t\t\t\t\t\tthis.remove()\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.onLeaveCompleted()\n\t\t\t\t\tresolve()\n\t\t\t\t})\n\t\t})\n\t}\n}\n","export default class RouteStore {\n\t/**\n\t * @type {Map>}\n\t */\n\tdata = new Map()\n\n\t/**\n\t * @type {Map}\n\t */\n\tregexCache = new Map()\n\n\t/**\n\t *\n\t * @param {string} fromPattern\n\t * @param {string} toPattern\n\t * @param {string} transition\n\t */\n\tadd(fromPattern, toPattern, transition) {\n\t\tif (!this.data.has(fromPattern)) {\n\t\t\tthis.data.set(fromPattern, new Map())\n\t\t\tthis.regexCache.set(fromPattern, new RegExp(`^${fromPattern}$`))\n\t\t}\n\n\t\tthis.data.get(fromPattern).set(toPattern, transition)\n\t\tthis.regexCache.set(toPattern, new RegExp(`^${toPattern}$`))\n\t}\n\n\t/**\n\t *\n\t * @param {{ raw: string, href: string, hasHash: boolean, pathname: string }} currentUrl\n\t * @param {{ raw: string, href: string, hasHash: boolean, pathname: string }} nextUrl\n\t * @return {string|null}\n\t */\n\tfindMatch(currentUrl, nextUrl) {\n\t\t// Loop through all from patterns\n\t\tfor (const [fromPattern, potentialMatches] of this.data) {\n\t\t\t// If we have a match\n\t\t\tif (currentUrl.pathname.match(this.regexCache.get(fromPattern))) {\n\t\t\t\t// loop through all associated to patterns\n\t\t\t\tfor (const [toPattern, transition] of potentialMatches) {\n\t\t\t\t\t// If we find a match, return it\n\t\t\t\t\tif (nextUrl.pathname.match(this.regexCache.get(toPattern))) {\n\t\t\t\t\t\treturn transition\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\treturn null\n\t}\n}\n","import E from '@unseenco/e'\nimport { appendElement, parseDom, processUrl, reloadElement } from './helpers'\nimport Transition from './Transition'\nimport Renderer from './Renderer'\nimport RouteStore from './RouteStore'\n\nconst IN_PROGRESS = 'A transition is currently in progress'\n\n/**\n * @typedef CacheEntry\n * @type {object}\n * @property {typeof Renderer|Renderer} renderer\n * @property {Document|Node} page\n * @property {array} scripts\n * @property {HTMLLinkElement[]} styles\n * @property {string} finalUrl\n * @property {boolean} skipCache\n * @property {string} title\n * @property {HTMLElement|Element} content\n */\n\nexport default class Core {\n\tisTransitioning = false\n\n\t/**\n\t * @type {CacheEntry|null}\n\t */\n\tcurrentCacheEntry = null\n\n\t/**\n\t * @type {Map}\n\t */\n\tcache = new Map()\n\n\t/**\n\t * @private\n\t * @type {Map}\n\t */\n\tactivePromises = new Map()\n\n\t/**\n\t * @param {{\n\t * \t\tlinks?: string,\n\t * \t\tremoveOldContent?: boolean,\n\t * \t\tallowInterruption?: boolean,\n\t * \t\tbypassCache?: boolean,\n\t * \t\tenablePrefetch?: boolean,\n\t * \t\trenderers?: Object.,\n\t * \t\ttransitions?: Object.,\n\t * \t\treloadJsFilter?: boolean|function(HTMLElement): boolean,\n\t * \t\treloadCssFilter?: boolean|function(HTMLLinkElement): boolean\n\t * }} parameters\n\t */\n\tconstructor(parameters = {}) {\n\t\tconst {\n\t\t\tlinks = 'a:not([target]):not([href^=\\\\#]):not([data-taxi-ignore])',\n\t\t\tremoveOldContent = true,\n\t\t\tallowInterruption = false,\n\t\t\tbypassCache = false,\n\t\t\tenablePrefetch = true,\n\t\t\trenderers = {\n\t\t\t\tdefault: Renderer\n\t\t\t},\n\t\t\ttransitions = {\n\t\t\t\tdefault: Transition\n\t\t\t},\n\t\t\treloadJsFilter = (element) => element.dataset.taxiReload !== undefined,\n\t\t\treloadCssFilter = (element) => true //element.dataset.taxiReload !== undefined\n\t\t} = parameters\n\n\t\tthis.renderers = renderers\n\t\tthis.transitions = transitions\n\t\tthis.defaultRenderer = this.renderers.default || Renderer\n\t\tthis.defaultTransition = this.transitions.default || Transition\n\t\tthis.wrapper = document.querySelector('[data-taxi]')\n\t\tthis.reloadJsFilter = reloadJsFilter\n\t\tthis.reloadCssFilter = reloadCssFilter\n\t\tthis.removeOldContent = removeOldContent\n\t\tthis.allowInterruption = allowInterruption\n\t\tthis.bypassCache = bypassCache\n\t\tthis.enablePrefetch = enablePrefetch\n\t\tthis.cache = new Map()\n\t\tthis.isPopping = false\n\n\t\t// Add delegated link events\n\t\tthis.attachEvents(links)\n\n\t\tthis.currentLocation = processUrl(window.location.href)\n\n\t\t// as this is the initial page load, prime this page into the cache\n\t\tthis.cache.set(this.currentLocation.href, this.createCacheEntry(document.cloneNode(true), window.location.href))\n\n\t\t// fire the current Renderer enter methods\n\t\tthis.currentCacheEntry = this.cache.get(this.currentLocation.href)\n\t\tthis.currentCacheEntry.renderer.initialLoad()\n\t}\n\n\t/**\n\t * @param {string} renderer\n\t */\n\tsetDefaultRenderer(renderer) {\n\t\tthis.defaultRenderer = this.renderers[renderer]\n\t}\n\n\t/**\n\t * @param {string} transition\n\t */\n\tsetDefaultTransition(transition) {\n\t\tthis.defaultTransition = this.transitions[transition]\n\t}\n\n\t/**\n\t * Registers a route into the RouteStore\n\t *\n\t * @param {string} fromPattern\n\t * @param {string} toPattern\n\t * @param {string} transition\n\t */\n\taddRoute(fromPattern, toPattern, transition) {\n\t\tif (!this.router) {\n\t\t\tthis.router = new RouteStore()\n\t\t}\n\n\t\tthis.router.add(fromPattern, toPattern, transition)\n\t}\n\n\t/**\n\t * Prime the cache for a given URL\n\t *\n\t * @param {string} url\n\t * @param {boolean} [preloadAssets]\n\t * @return {Promise}\n\t */\n\tpreload(url, preloadAssets = false) {\n\t\t// convert relative URLs to absolute\n\t\turl = processUrl(url).href\n\n\t\tif (!this.cache.has(url)) {\n\t\t\treturn this.fetch(url, false)\n\t\t\t\t.then(async (response) => {\n\t\t\t\t\tthis.cache.set(url, this.createCacheEntry(response.html, response.url))\n\n\t\t\t\t\tif (preloadAssets) {\n\t\t\t\t\t\tthis.cache.get(url).renderer.createDom()\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\t.catch(err => console.warn(err))\n\t\t}\n\n\t\treturn Promise.resolve()\n\t}\n\n\t/**\n\t * Updates the HTML cache for a given URL.\n\t * If no URL is passed, then cache for the current page is updated.\n\t * Useful when adding/removing content via AJAX such as a search page or infinite loader.\n\t *\n\t * @param {string} [url]\n\t */\n\tupdateCache(url) {\n\t\tconst key = processUrl(url || window.location.href).href\n\n\t\tif (this.cache.has(key)) {\n\t\t\tthis.cache.delete(key)\n\t\t}\n\n\t\tthis.cache.set(key, this.createCacheEntry(document.cloneNode(true), key))\n\t}\n\n\t/**\n\t * Clears the cache for a given URL.\n\t * If no URL is passed, then cache for the current page is cleared.\n\t *\n\t * @param {string} [url]\n\t */\n\tclearCache(url) {\n\t\tconst key = processUrl(url || window.location.href).href\n\n\t\tif (this.cache.has(key)) {\n\t\t\tthis.cache.delete(key)\n\t\t}\n\t}\n\n\t/**\n\t * @param {string} url\n\t * @param {string|false} [transition]\n\t * @param {string|false|HTMLElement} [trigger]\n\t * @return {Promise}\n\t */\n\tnavigateTo(url, transition = false, trigger = false) {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\t// Don't allow multiple navigations to occur at once\n\t\t\tif (!this.allowInterruption && this.isTransitioning) {\n\t\t\t\treject(new Error(IN_PROGRESS))\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tthis.isTransitioning = true\n\t\t\tthis.isPopping = true\n\t\t\tthis.targetLocation = processUrl(url)\n\t\t\tthis.popTarget = window.location.href\n\n\t\t\tconst TransitionClass = new (this.chooseTransition(transition))({ wrapper: this.wrapper })\n\n\t\t\tlet navigationPromise\n\n\t\t\tif (this.bypassCache || !this.cache.has(this.targetLocation.href) || this.cache.get(this.targetLocation.href).skipCache) {\n\t\t\t\tconst fetched = this.fetch(this.targetLocation.href)\n\t\t\t\t\t.then((response) => {\n\t\t\t\t\t\tthis.cache.set(this.targetLocation.href, this.createCacheEntry(response.html, response.url))\n\t\t\t\t\t\tthis.cache.get(this.targetLocation.href).renderer.createDom()\n\t\t\t\t\t})\n\t\t\t\t\t.catch(err => {\n\t\t\t\t\t\t// we encountered a 4** or 5** error, redirect to the requested URL\n\t\t\t\t\t\twindow.location.href = url\n\t\t\t\t\t})\n\n\t\t\t\tnavigationPromise = this.beforeFetch(this.targetLocation, TransitionClass, trigger)\n\t\t\t\t\t.then(async () => {\n\t\t\t\t\t\treturn fetched.then(async () => {\n\t\t\t\t\t\t\treturn await this.afterFetch(this.targetLocation, TransitionClass, this.cache.get(this.targetLocation.href), trigger)\n\t\t\t\t\t\t})\n\t\t\t\t\t})\n\t\t\t} else {\n\t\t\t\tthis.cache.get(this.targetLocation.href).renderer.createDom()\n\n\t\t\t\tnavigationPromise = this.beforeFetch(this.targetLocation, TransitionClass, trigger)\n\t\t\t\t\t.then(async () => {\n\t\t\t\t\t\treturn await this.afterFetch(this.targetLocation, TransitionClass, this.cache.get(this.targetLocation.href), trigger)\n\t\t\t\t\t})\n\t\t\t}\n\n\t\t\tnavigationPromise.then(() => {\n\t\t\t\tresolve()\n\t\t\t})\n\t\t})\n\t}\n\n\t/**\n\t * Add an event listener.\n\t * @param {string} event\n\t * @param {any} callback\n\t */\n\ton(event, callback) {\n\t\tE.on(event, callback)\n\t}\n\n\t/**\n\t * Remove an event listener.\n\t * @param {string} event\n\t * @param {any} [callback]\n\t */\n\toff(event, callback) {\n\t\tE.off(event, callback)\n\t}\n\n\t/**\n\t * @private\n\t * @param {{ raw: string, href: string, hasHash: boolean, pathname: string }} url\n\t * @param {Transition} TransitionClass\n\t * @param {string|HTMLElement|false} trigger\n\t * @return {Promise}\n\t */\n\tbeforeFetch(url, TransitionClass, trigger) {\n\t\tE.emit('NAVIGATE_OUT', {\n\t\t\tfrom: this.currentCacheEntry,\n\t\t\ttrigger\n\t\t})\n\n\t\treturn new Promise((resolve) => {\n\t\t\tthis.currentCacheEntry.renderer.leave(TransitionClass, trigger, this.removeOldContent)\n\t\t\t\t.then(() => {\n\t\t\t\t\tif (trigger !== 'popstate') {\n\t\t\t\t\t\twindow.history.pushState({}, '', url.raw)\n\t\t\t\t\t}\n\n\t\t\t\t\tresolve()\n\t\t\t\t})\n\t\t})\n\t}\n\n\t/**\n\t * @private\n\t * @param {{ raw: string, href: string, host: string, hasHash: boolean, pathname: string }} url\n\t * @param {Transition} TransitionClass\n\t * @param {CacheEntry} entry\n\t * @param {string|HTMLElement|false} trigger\n\t * @return {Promise}\n\t */\n\tafterFetch(url, TransitionClass, entry, trigger) {\n\t\tthis.currentLocation = url\n\t\tthis.popTarget = this.currentLocation.href\n\n\t\treturn new Promise((resolve) => {\n\t\t\tentry.renderer.update()\n\n\t\t\tE.emit('NAVIGATE_IN', {\n\t\t\t\tfrom: this.currentCacheEntry,\n\t\t\t\tto: entry,\n\t\t\t\ttrigger\n\t\t\t})\n\n\t\t\tif (this.reloadJsFilter) {\n\t\t\t\tthis.loadScripts(entry.scripts)\n\t\t\t}\n\n\t\t\tif (this.reloadCssFilter) {\n\t\t\t\tthis.loadStyles(entry.styles)\n\t\t\t}\n\n\t\t\t// If the fetched url had a redirect chain, then replace the history to reflect the final resolved URL\n\t\t\tif (trigger !== 'popstate' && url.href !== entry.finalUrl) {\n\t\t\t\twindow.history.replaceState({}, '', entry.finalUrl)\n\t\t\t}\n\n\t\t\tentry.renderer.enter(TransitionClass, trigger)\n\t\t\t\t.then(() => {\n\t\t\t\t\tE.emit('NAVIGATE_END', {\n\t\t\t\t\t\tfrom: this.currentCacheEntry,\n\t\t\t\t\t\tto: entry,\n\t\t\t\t\t\ttrigger\n\t\t\t\t\t})\n\n\t\t\t\t\tthis.currentCacheEntry = entry\n\t\t\t\t\tthis.isTransitioning = false\n\t\t\t\t\tthis.isPopping = false\n\t\t\t\t\tresolve()\n\t\t\t\t})\n\t\t})\n\t}\n\n\t/**\n\t * Load up scripts from the target page if needed\n\t *\n\t * @param {HTMLElement[]} cachedScripts\n\t */\n\tloadScripts(cachedScripts) {\n\t\tconst newScripts = [...cachedScripts]\n\t\tconst currentScripts = Array.from(document.querySelectorAll('script')).filter(this.reloadJsFilter)\n\n\t\t// loop through all new scripts\n\t\tfor (let i = 0; i < currentScripts.length; i++) {\n\t\t\tfor (let n = 0; n < newScripts.length; n++) {\n\t\t\t\tif (currentScripts[i].outerHTML === newScripts[n].outerHTML) {\n\t\t\t\t\treloadElement(currentScripts[i], 'SCRIPT')\n\t\t\t\t\tnewScripts.splice(n, 1)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tfor (const script of newScripts) {\n\t\t\tappendElement(script, 'SCRIPT')\n\t\t}\n\t}\n\n\t/**\n\t * Load up styles from the target page if needed\n\t *\n\t * @param {Array} cachedStyles\n\t */\n\tloadStyles(cachedStyles) {\n\t\tconst currentStyles = Array.from(document.querySelectorAll('link[rel=\"stylesheet\"]')).filter(this.reloadCssFilter)\n\t\tconst currentInlineStyles = Array.from(document.querySelectorAll('style')).filter(this.reloadCssFilter)\n\n\t\tconst newInlineStyles = cachedStyles.filter(el => {\n\t\t\t// no el.href, assume it's an inline style\n\t\t\tif (!el.href) {\n\t\t\t\treturn true\n\t\t\t} else if (!currentStyles.find((link) => link.href === el.href)) {\n\t\t\t\tdocument.body.append(el)\n\t\t\t\treturn false\n\t\t\t}\n\t\t})\n\n\t\t// loop through all new inline styles\n\t\tfor (let i = 0; i < currentInlineStyles.length; i++) {\n\t\t\tfor (let n = 0; n < newInlineStyles.length; n++) {\n\t\t\t\tif (currentInlineStyles[i].outerHTML === newInlineStyles[n].outerHTML) {\n\t\t\t\t\treloadElement(currentInlineStyles[i], 'STYLE')\n\t\t\t\t\tnewInlineStyles.splice(n, 1)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tfor (const style of newInlineStyles) {\n\t\t\tappendElement(style, 'STYLE')\n\t\t}\n\t}\n\n\t/**\n\t * @private\n\t * @param {string} links\n\t */\n\tattachEvents(links) {\n\t\tE.delegate('click', links, this.onClick)\n\t\tE.on('popstate', window, this.onPopstate)\n\n\t\tif (this.enablePrefetch) {\n\t\t\tE.delegate('mouseenter focus', links, this.onPrefetch)\n\t\t}\n\t}\n\n\t/**\n\t * @private\n\t * @param {MouseEvent} e\n\t */\n\tonClick = (e) => {\n\t\tif (!(e.metaKey || e.ctrlKey)) {\n\t\t\tconst target = processUrl(e.currentTarget.href)\n\t\t\tthis.currentLocation = processUrl(window.location.href)\n\n\t\t\tif (this.currentLocation.host !== target.host) {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// the target is a new URL, or is removing the hash from the current URL\n\t\t\tif (this.currentLocation.href !== target.href || (this.currentLocation.hasHash && !target.hasHash)) {\n\t\t\t\te.preventDefault()\n\t\t\t\t// noinspection JSIgnoredPromiseFromCall\n\t\t\t\tthis.navigateTo(target.raw, e.currentTarget.dataset.transition || false, e.currentTarget).catch(err => console.warn(err))\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// a click to the current URL was detected\n\t\t\tif (!this.currentLocation.hasHash && !target.hasHash) {\n\t\t\t\te.preventDefault()\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * @private\n\t * @return {void|boolean}\n\t */\n\tonPopstate = () => {\n\t\t// don't trigger for on-page anchors\n\t\tif (\n\t\t\twindow.location.pathname === this.currentLocation.pathname\n\t\t\t&& window.location.search === this.currentLocation.search\n\t\t\t&& !this.isPopping\n\t\t) {\n\t\t\treturn false\n\t\t}\n\n\t\tif (!this.allowInterruption && (this.isTransitioning || this.isPopping)) {\n\t\t\t// overwrite history state with current page if currently navigating\n\t\t\twindow.history.pushState({}, '', this.popTarget)\n\t\t\tconsole.warn(IN_PROGRESS)\n\t\t\treturn false\n\t\t}\n\n\t\tif (!this.isPopping) {\n\t\t\tthis.popTarget = window.location.href\n\t\t}\n\n\t\tthis.isPopping = true\n\n\t\t// noinspection JSIgnoredPromiseFromCall\n\t\tthis.navigateTo(window.location.href, false, 'popstate')\n\t}\n\n\t/**\n\t * @private\n\t * @param {MouseEvent} e\n\t */\n\tonPrefetch = (e) => {\n\t\tconst target = processUrl(e.currentTarget.href)\n\n\t\tif (this.currentLocation.host !== target.host) {\n\t\t\treturn\n\t\t}\n\n\t\tthis.preload(e.currentTarget.href, false)\n\t}\n\n\t/**\n\t * @private\n\t * @param {string} url\n\t * @param {boolean} [runFallback]\n\t * @return {Promise<{html: Document, url: string}>}\n\t */\n\tfetch(url, runFallback = true) {\n\t\t// If Taxi is currently performing a fetch for the given URL, return that instead of starting a new request\n\t\tif (this.activePromises.has(url)) {\n\t\t\treturn this.activePromises.get(url)\n\t\t}\n\n\t\tconst request = new Promise((resolve, reject) => {\n\t\t\tlet resolvedUrl\n\n\t\t\tfetch(url, {\n\t\t\t\tmode: 'same-origin',\n\t\t\t\tmethod: 'GET',\n\t\t\t\theaders: { 'X-Requested-With': 'Taxi' },\n\t\t\t\tcredentials: 'same-origin'\n\t\t\t})\n\t\t\t\t.then((response) => {\n\t\t\t\t\tif (!response.ok) {\n\t\t\t\t\t\treject('Taxi encountered a non 2xx HTTP status code')\n\n\t\t\t\t\t\tif (runFallback) {\n\t\t\t\t\t\t\twindow.location.href = url\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tresolvedUrl = response.url\n\n\t\t\t\t\treturn response.text()\n\t\t\t\t})\n\t\t\t\t.then((htmlString) => {\n\t\t\t\t\tresolve({ html: parseDom(htmlString), url: resolvedUrl })\n\t\t\t\t})\n\t\t\t\t.catch((err) => {\n\t\t\t\t\treject(err)\n\n\t\t\t\t\tif (runFallback) {\n\t\t\t\t\t\twindow.location.href = url\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\t.finally(() => {\n\t\t\t\t\tthis.activePromises.delete(url)\n\t\t\t\t})\n\t\t})\n\n\t\tthis.activePromises.set(url, request)\n\n\t\treturn request\n\t}\n\n\t/**\n\t * @private\n\t * @param {string|false} transition\n\t * @return {Transition|function}\n\t */\n\tchooseTransition(transition) {\n\t\tif (transition) {\n\t\t\treturn this.transitions[transition]\n\t\t}\n\n\t\tconst routeTransition = this.router?.findMatch(this.currentLocation, this.targetLocation)\n\n\t\tif (routeTransition) {\n\t\t\treturn this.transitions[routeTransition]\n\t\t}\n\n\t\treturn this.defaultTransition\n\t}\n\n\t/**\n\t * @private\n\t * @param {Document|Node} page\n\t * @param {string} url\n\t * @return {CacheEntry}\n\t */\n\tcreateCacheEntry(page, url) {\n\t\tconst content = page.querySelector('[data-taxi-view]')\n\t\tconst Renderer = content.dataset.taxiView.length ? this.renderers[content.dataset.taxiView] : this.defaultRenderer\n\n\t\tif (!Renderer) {\n\t\t\tconsole.warn(`The Renderer \"${content.dataset.taxiView}\" was set in the data-taxi-view of the requested page, but not registered in Taxi.`)\n\t\t}\n\n\t\treturn {\n\t\t\tpage,\n\t\t\tcontent,\n\t\t\tfinalUrl: url,\n\t\t\tskipCache: content.hasAttribute('data-taxi-nocache'),\n\t\t\tscripts: this.reloadJsFilter ? Array.from(page.querySelectorAll('script')).filter(this.reloadJsFilter) : [],\n\t\t\tstyles: this.reloadCssFilter ? Array.from(page.querySelectorAll('link[rel=\"stylesheet\"], style')).filter(this.reloadCssFilter) : [],\n\t\t\ttitle: page.title,\n\t\t\trenderer: new Renderer({\n\t\t\t\twrapper: this.wrapper,\n\t\t\t\ttitle: page.title,\n\t\t\t\tcontent,\n\t\t\t\tpage\n\t\t\t})\n\t\t}\n\t}\n}\n"],"names":["parser","DOMParser","processUrl","url","details","URL","window","location","origin","normalized","hash","length","replace","hasHash","pathname","host","search","raw","href","reloadElement","node","elementType","parentNode","replaceChild","duplicateElement","appendElement","tagName","document","head","body","appendChild","replacement","createElement","k","attributes","attr","setAttribute","nodeName","nodeValue","innerHTML","Transition","this","wrapper","leave","props","Promise","resolve","_this","onLeave","done","enter","_this2","onEnter","Renderer","page","title","_contentString","content","outerHTML","_DOM","lastElementChild","onEnterCompleted","onLeaveCompleted","initialLoad","update","firstElementChild","createDom","remove","transition","trigger","to","then","removeOldContent","from","RouteStore","data","Map","regexCache","add","fromPattern","toPattern","has","set","RegExp","get","findMatch","currentUrl","nextUrl","potentialMatches","match","IN_PROGRESS","Core","parameters","isTransitioning","currentCacheEntry","cache","activePromises","onClick","e","metaKey","ctrlKey","target","currentTarget","currentLocation","preventDefault","navigateTo","dataset","err","console","warn","onPopstate","isPopping","allowInterruption","popTarget","history","pushState","onPrefetch","preload","links","bypassCache","enablePrefetch","renderers","transitions","default","reloadJsFilter","element","undefined","taxiReload","reloadCssFilter","defaultRenderer","defaultTransition","querySelector","attachEvents","createCacheEntry","cloneNode","renderer","setDefaultRenderer","setDefaultTransition","addRoute","router","preloadAssets","fetch","response","html","updateCache","key","clearCache","reject","_this3","targetLocation","navigationPromise","TransitionClass","chooseTransition","skipCache","fetched","beforeFetch","afterFetch","Error","on","event","callback","E","off","emit","_this4","entry","_this5","loadScripts","scripts","loadStyles","styles","finalUrl","replaceState","cachedScripts","newScripts","currentScripts","Array","querySelectorAll","filter","i","n","splice","cachedStyles","currentStyles","currentInlineStyles","newInlineStyles","el","find","link","append","delegate","runFallback","request","resolvedUrl","mode","method","headers","credentials","ok","text","htmlString","parseFromString","_this6","routeTransition","_this$router","taxiView","hasAttribute"],"mappings":"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"} \ No newline at end of file diff --git a/dist/taxi.js b/dist/taxi.js index 2ee58d7..2c4f5f3 100644 --- a/dist/taxi.js +++ b/dist/taxi.js @@ -1,2 +1,2 @@ -function t(t){return t&&"object"==typeof t&&"default"in t?t:{default:t}}var e=/*#__PURE__*/t(require("@unseenco/e"));function r(){return r=Object.assign||function(t){for(var e=1;et.length)&&(e=t.length);for(var r=0,n=new Array(e);r=t.length?{done:!0}:{done:!1,value:t[i++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var o=new DOMParser;function a(t){var e=new URL(t,window.location.origin),r=e.hash.length?t.replace(e.hash,""):null;return{hasHash:e.hash.length>0,pathname:e.pathname,host:e.host,raw:t,href:r||e.href}}function c(t,e){t.parentNode.replaceChild(h(t,e),t)}function s(t,e){("HEAD"===t.parentNode.tagName?document.head:document.body).appendChild(h(t,e))}function h(t,e){for(var r=document.createElement(e),n=0;nt.length)&&(e=t.length);for(var r=0,n=new Array(e);r=t.length?{done:!0}:{done:!1,value:t[i++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var o=new DOMParser;function a(t){var e=new URL(t,window.location.origin),r=e.hash.length?t.replace(e.hash,""):null;return{hasHash:e.hash.length>0,pathname:e.pathname,host:e.host,search:e.search,raw:t,href:r||e.href}}function c(t,e){t.parentNode.replaceChild(h(t,e),t)}function s(t,e){("HEAD"===t.parentNode.tagName?document.head:document.body).appendChild(h(t,e))}function h(t,e){for(var r=document.createElement(e),n=0;n 0,\n\t\tpathname: details.pathname,\n\t\thost: details.host,\n\t\traw: url,\n\t\thref: normalized || details.href\n\t}\n}\n\n/**\n * Reloads a provided script/stylesheet by replacing with itself.\n *\n * @param {HTMLElement|HTMLScriptElement|HTMLStyleElement} node\n * @param {string} elementType - 'SCRIPT' or 'STYLE'\n */\nexport function reloadElement(node, elementType) {\n\tnode.parentNode.replaceChild(duplicateElement(node, elementType), node)\n}\n\n/**\n * Loads a provided script/stylesheet by appending a clone to the current document.\n *\n * @param {HTMLElement|HTMLStyleElement} node\n * @param {string} elementType - 'SCRIPT' or 'STYLE'\n */\nexport function appendElement(node, elementType) {\n\tconst target = node.parentNode.tagName === 'HEAD' ? document.head : document.body\n\ttarget.appendChild(duplicateElement(node, elementType))\n}\n\n/**\n * Creates a clone of a given HTMLElement or HTMLStyleElement\n *\n * @param {HTMLElement|HTMLStyleElement} node\n * @param {string} elementType - 'SCRIPT' or 'STYLE'\n * @return {HTMLElement|HTMLStyleElement}\n */\nexport function duplicateElement(node, elementType) {\n\tconst replacement = document.createElement(elementType)\n\n\tfor (let k = 0; k < node.attributes.length; k++) {\n\t\tconst attr = node.attributes[k]\n\t\treplacement.setAttribute(attr.nodeName, attr.nodeValue)\n\t}\n\n\t// Inline Script or Style\n\tif (node.innerHTML) {\n\t\treplacement.innerHTML = node.innerHTML\n\t}\n\n\treturn replacement\n}\n","export default class Transition {\n\t/**\n\t * @param {{wrapper: HTMLElement}} props\n\t */\n\tconstructor({ wrapper }) {\n\t\tthis.wrapper = wrapper\n\t}\n\n\t/**\n\t * @param {{ from: HTMLElement|Element, trigger: string|HTMLElement|false }} props\n\t * @return {Promise}\n\t */\n\tleave(props) {\n\t\treturn new Promise((resolve) => {\n\t\t\tthis.onLeave({ ...props, done: resolve })\n\t\t})\n\t}\n\n\t/**\n\t * @param {{ to: HTMLElement|Element, trigger: string|HTMLElement|false }} props\n\t * @return {Promise}\n\t */\n\tenter(props) {\n\t\treturn new Promise((resolve) => {\n\t\t\tthis.onEnter({ ...props, done: resolve })\n\t\t})\n\t}\n\n\t/**\n\t * Handle the transition leaving the previous page.\n\t * @param {{from: HTMLElement|Element, trigger: string|HTMLElement|false, done: function}} props\n\t */\n\tonLeave({ from, trigger, done }) {\n\t\tdone()\n\t}\n\n\t/**\n\t * Handle the transition entering the next page.\n\t * @param {{to: HTMLElement|Element, trigger: string|HTMLElement|false, done: function}} props\n\t */\n\tonEnter({ to, trigger, done }) {\n\t\tdone()\n\t}\n}\n","import Transition from \"./Transition\"\n\nexport default class Renderer {\n\t/**\n\t * @param {{content: HTMLElement|Element, page: Document|Node, title: string, wrapper: Element}} props\n\t */\n\tconstructor({ content, page, title, wrapper }) {\n\t\tthis._contentString = content.outerHTML\n\t\tthis._DOM = null\n\t\tthis.page = page\n\t\tthis.title = title\n\t\tthis.wrapper = wrapper\n\t\tthis.content = this.wrapper.lastElementChild\n\t}\n\n\tonEnter() {\n\n\t}\n\n\tonEnterCompleted() {\n\n\t}\n\n\tonLeave() {\n\n\t}\n\n\tonLeaveCompleted() {\n\n\t}\n\n\tinitialLoad() {\n\t\tthis.onEnter()\n\t\tthis.onEnterCompleted()\n\t}\n\n\tupdate() {\n\t\tdocument.title = this.title\n\t\tthis.wrapper.appendChild(this._DOM.firstElementChild)\n\t\tthis.content = this.wrapper.lastElementChild\n\t\tthis._DOM = null\n\t}\n\n\tcreateDom() {\n\t\tif (!this._DOM) {\n\t\t\tthis._DOM = document.createElement('div')\n\t\t\tthis._DOM.innerHTML = this._contentString\n\t\t}\n\t}\n\n\tremove() {\n\t\tthis.wrapper.firstElementChild.remove()\n\t}\n\n\t/**\n\t * Called when transitioning into the current page.\n\t * @param {Transition} transition\n\t * @param {string|HTMLElement|false} trigger\n\t * @return {Promise}\n\t */\n\tenter(transition, trigger) {\n\t\treturn new Promise((resolve) => {\n\t\t\tthis.onEnter()\n\n\t\t\ttransition.enter({ trigger, to: this.content })\n\t\t\t\t.then(() => {\n\t\t\t\t\tthis.onEnterCompleted()\n\t\t\t\t\tresolve()\n\t\t\t\t})\n\t\t})\n\t}\n\n\t/**\n\t * Called when transitioning away from the current page.\n\t * @param {Transition} transition\n\t * @param {string|HTMLElement|false} trigger\n\t * @param {boolean} removeOldContent\n\t * @return {Promise}\n\t */\n\tleave(transition, trigger, removeOldContent) {\n\t\treturn new Promise((resolve) => {\n\t\t\tthis.onLeave()\n\n\t\t\ttransition.leave({ trigger, from: this.content })\n\t\t\t\t.then(() => {\n\t\t\t\t\tif (removeOldContent) {\n\t\t\t\t\t\tthis.remove()\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.onLeaveCompleted()\n\t\t\t\t\tresolve()\n\t\t\t\t})\n\t\t})\n\t}\n}\n","export default class RouteStore {\n\t/**\n\t * @type {Map>}\n\t */\n\tdata = new Map()\n\n\t/**\n\t * @type {Map}\n\t */\n\tregexCache = new Map()\n\n\t/**\n\t *\n\t * @param {string} fromPattern\n\t * @param {string} toPattern\n\t * @param {string} transition\n\t */\n\tadd(fromPattern, toPattern, transition) {\n\t\tif (!this.data.has(fromPattern)) {\n\t\t\tthis.data.set(fromPattern, new Map())\n\t\t\tthis.regexCache.set(fromPattern, new RegExp(`^${fromPattern}$`))\n\t\t}\n\n\t\tthis.data.get(fromPattern).set(toPattern, transition)\n\t\tthis.regexCache.set(toPattern, new RegExp(`^${toPattern}$`))\n\t}\n\n\t/**\n\t *\n\t * @param {{ raw: string, href: string, hasHash: boolean, pathname: string }} currentUrl\n\t * @param {{ raw: string, href: string, hasHash: boolean, pathname: string }} nextUrl\n\t * @return {string|null}\n\t */\n\tfindMatch(currentUrl, nextUrl) {\n\t\t// Loop through all from patterns\n\t\tfor (const [fromPattern, potentialMatches] of this.data) {\n\t\t\t// If we have a match\n\t\t\tif (currentUrl.pathname.match(this.regexCache.get(fromPattern))) {\n\t\t\t\t// loop through all associated to patterns\n\t\t\t\tfor (const [toPattern, transition] of potentialMatches) {\n\t\t\t\t\t// If we find a match, return it\n\t\t\t\t\tif (nextUrl.pathname.match(this.regexCache.get(toPattern))) {\n\t\t\t\t\t\treturn transition\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\treturn null\n\t}\n}\n","import E from '@unseenco/e'\nimport { appendElement, parseDom, processUrl, reloadElement } from './helpers'\nimport Transition from './Transition'\nimport Renderer from './Renderer'\nimport RouteStore from './RouteStore'\n\nconst IN_PROGRESS = 'A transition is currently in progress'\n\n/**\n * @typedef CacheEntry\n * @type {object}\n * @property {typeof Renderer|Renderer} renderer\n * @property {Document|Node} page\n * @property {array} scripts\n * @property {HTMLLinkElement[]} styles\n * @property {string} finalUrl\n * @property {boolean} skipCache\n * @property {string} title\n * @property {HTMLElement|Element} content\n */\n\nexport default class Core {\n\tisTransitioning = false\n\n\t/**\n\t * @type {CacheEntry|null}\n\t */\n\tcurrentCacheEntry = null\n\n\t/**\n\t * @type {Map}\n\t */\n\tcache = new Map()\n\n\t/**\n\t * @private\n\t * @type {Map}\n\t */\n\tactivePromises = new Map()\n\n\t/**\n\t * @param {{\n\t * \t\tlinks?: string,\n\t * \t\tremoveOldContent?: boolean,\n\t * \t\tallowInterruption?: boolean,\n\t * \t\tbypassCache?: boolean,\n\t * \t\tenablePrefetch?: boolean,\n\t * \t\trenderers?: Object.,\n\t * \t\ttransitions?: Object.,\n\t * \t\treloadJsFilter?: boolean|function(HTMLElement): boolean,\n\t * \t\treloadCssFilter?: boolean|function(HTMLLinkElement): boolean\n\t * }} parameters\n\t */\n\tconstructor(parameters = {}) {\n\t\tconst {\n\t\t\tlinks = 'a:not([target]):not([href^=\\\\#]):not([data-taxi-ignore])',\n\t\t\tremoveOldContent = true,\n\t\t\tallowInterruption = false,\n\t\t\tbypassCache = false,\n\t\t\tenablePrefetch = true,\n\t\t\trenderers = {\n\t\t\t\tdefault: Renderer\n\t\t\t},\n\t\t\ttransitions = {\n\t\t\t\tdefault: Transition\n\t\t\t},\n\t\t\treloadJsFilter = (element) => element.dataset.taxiReload !== undefined,\n\t\t\treloadCssFilter = (element) => true //element.dataset.taxiReload !== undefined\n\t\t} = parameters\n\n\t\tthis.renderers = renderers\n\t\tthis.transitions = transitions\n\t\tthis.defaultRenderer = this.renderers.default || Renderer\n\t\tthis.defaultTransition = this.transitions.default || Transition\n\t\tthis.wrapper = document.querySelector('[data-taxi]')\n\t\tthis.reloadJsFilter = reloadJsFilter\n\t\tthis.reloadCssFilter = reloadCssFilter\n\t\tthis.removeOldContent = removeOldContent\n\t\tthis.allowInterruption = allowInterruption\n\t\tthis.bypassCache = bypassCache\n\t\tthis.enablePrefetch = enablePrefetch\n\t\tthis.cache = new Map()\n\t\tthis.isPopping = false\n\n\t\t// Add delegated link events\n\t\tthis.attachEvents(links)\n\n\t\tthis.currentLocation = processUrl(window.location.href)\n\n\t\t// as this is the initial page load, prime this page into the cache\n\t\tthis.cache.set(this.currentLocation.href, this.createCacheEntry(document.cloneNode(true), window.location.href))\n\n\t\t// fire the current Renderer enter methods\n\t\tthis.currentCacheEntry = this.cache.get(this.currentLocation.href)\n\t\tthis.currentCacheEntry.renderer.initialLoad()\n\t}\n\n\t/**\n\t * @param {string} renderer\n\t */\n\tsetDefaultRenderer(renderer) {\n\t\tthis.defaultRenderer = this.renderers[renderer]\n\t}\n\n\t/**\n\t * @param {string} transition\n\t */\n\tsetDefaultTransition(transition) {\n\t\tthis.defaultTransition = this.transitions[transition]\n\t}\n\n\t/**\n\t * Registers a route into the RouteStore\n\t *\n\t * @param {string} fromPattern\n\t * @param {string} toPattern\n\t * @param {string} transition\n\t */\n\taddRoute(fromPattern, toPattern, transition) {\n\t\tif (!this.router) {\n\t\t\tthis.router = new RouteStore()\n\t\t}\n\n\t\tthis.router.add(fromPattern, toPattern, transition)\n\t}\n\n\t/**\n\t * Prime the cache for a given URL\n\t *\n\t * @param {string} url\n\t * @param {boolean} [preloadAssets]\n\t * @return {Promise}\n\t */\n\tpreload(url, preloadAssets = false) {\n\t\t// convert relative URLs to absolute\n\t\turl = processUrl(url).href\n\n\t\tif (!this.cache.has(url)) {\n\t\t\treturn this.fetch(url, false)\n\t\t\t\t.then(async (response) => {\n\t\t\t\t\tthis.cache.set(url, this.createCacheEntry(response.html, response.url))\n\n\t\t\t\t\tif (preloadAssets) {\n\t\t\t\t\t\tthis.cache.get(url).renderer.createDom()\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\t.catch(err => console.warn(err))\n\t\t}\n\n\t\treturn Promise.resolve()\n\t}\n\n\t/**\n\t * Updates the HTML cache for a given URL.\n\t * If no URL is passed, then cache for the current page is updated.\n\t * Useful when adding/removing content via AJAX such as a search page or infinite loader.\n\t *\n\t * @param {string} [url]\n\t */\n\tupdateCache(url) {\n\t\tconst key = processUrl(url || window.location.href).href\n\n\t\tif (this.cache.has(key)) {\n\t\t\tthis.cache.delete(key)\n\t\t}\n\n\t\tthis.cache.set(key, this.createCacheEntry(document.cloneNode(true), key))\n\t}\n\n\t/**\n\t * Clears the cache for a given URL.\n\t * If no URL is passed, then cache for the current page is cleared.\n\t *\n\t * @param {string} [url]\n\t */\n\tclearCache(url) {\n\t\tconst key = processUrl(url || window.location.href).href\n\n\t\tif (this.cache.has(key)) {\n\t\t\tthis.cache.delete(key)\n\t\t}\n\t}\n\n\t/**\n\t * @param {string} url\n\t * @param {string|false} [transition]\n\t * @param {string|false|HTMLElement} [trigger]\n\t * @return {Promise}\n\t */\n\tnavigateTo(url, transition = false, trigger = false) {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\t// Don't allow multiple navigations to occur at once\n\t\t\tif (!this.allowInterruption && this.isTransitioning) {\n\t\t\t\treject(new Error(IN_PROGRESS))\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tthis.isTransitioning = true\n\t\t\tthis.isPopping = true\n\t\t\tthis.targetLocation = processUrl(url)\n\t\t\tthis.popTarget = window.location.href\n\n\t\t\tconst TransitionClass = new (this.chooseTransition(transition))({ wrapper: this.wrapper })\n\n\t\t\tlet navigationPromise\n\n\t\t\tif (this.bypassCache || !this.cache.has(this.targetLocation.href) || this.cache.get(this.targetLocation.href).skipCache) {\n\t\t\t\tconst fetched = this.fetch(this.targetLocation.href)\n\t\t\t\t\t.then((response) => {\n\t\t\t\t\t\tthis.cache.set(this.targetLocation.href, this.createCacheEntry(response.html, response.url))\n\t\t\t\t\t\tthis.cache.get(this.targetLocation.href).renderer.createDom()\n\t\t\t\t\t})\n\t\t\t\t\t.catch(err => {\n\t\t\t\t\t\t// we encountered a 4** or 5** error, redirect to the requested URL\n\t\t\t\t\t\twindow.location.href = url\n\t\t\t\t\t})\n\n\t\t\t\tnavigationPromise = this.beforeFetch(this.targetLocation, TransitionClass, trigger)\n\t\t\t\t\t.then(async () => {\n\t\t\t\t\t\treturn fetched.then(async () => {\n\t\t\t\t\t\t\treturn await this.afterFetch(this.targetLocation, TransitionClass, this.cache.get(this.targetLocation.href), trigger)\n\t\t\t\t\t\t})\n\t\t\t\t\t})\n\t\t\t} else {\n\t\t\t\tthis.cache.get(this.targetLocation.href).renderer.createDom()\n\n\t\t\t\tnavigationPromise = this.beforeFetch(this.targetLocation, TransitionClass, trigger)\n\t\t\t\t\t.then(async () => {\n\t\t\t\t\t\treturn await this.afterFetch(this.targetLocation, TransitionClass, this.cache.get(this.targetLocation.href), trigger)\n\t\t\t\t\t})\n\t\t\t}\n\n\t\t\tnavigationPromise.then(() => {\n\t\t\t\tresolve()\n\t\t\t})\n\t\t})\n\t}\n\n\t/**\n\t * Add an event listener.\n\t * @param {string} event\n\t * @param {any} callback\n\t */\n\ton(event, callback) {\n\t\tE.on(event, callback)\n\t}\n\n\t/**\n\t * Remove an event listener.\n\t * @param {string} event\n\t * @param {any} [callback]\n\t */\n\toff(event, callback) {\n\t\tE.off(event, callback)\n\t}\n\n\t/**\n\t * @private\n\t * @param {{ raw: string, href: string, hasHash: boolean, pathname: string }} url\n\t * @param {Transition} TransitionClass\n\t * @param {string|HTMLElement|false} trigger\n\t * @return {Promise}\n\t */\n\tbeforeFetch(url, TransitionClass, trigger) {\n\t\tE.emit('NAVIGATE_OUT', {\n\t\t\tfrom: this.currentCacheEntry,\n\t\t\ttrigger\n\t\t})\n\n\t\treturn new Promise((resolve) => {\n\t\t\tthis.currentCacheEntry.renderer.leave(TransitionClass, trigger, this.removeOldContent)\n\t\t\t\t.then(() => {\n\t\t\t\t\tif (trigger !== 'popstate') {\n\t\t\t\t\t\twindow.history.pushState({}, '', url.raw)\n\t\t\t\t\t}\n\n\t\t\t\t\tresolve()\n\t\t\t\t})\n\t\t})\n\t}\n\n\t/**\n\t * @private\n\t * @param {{ raw: string, href: string, host: string, hasHash: boolean, pathname: string }} url\n\t * @param {Transition} TransitionClass\n\t * @param {CacheEntry} entry\n\t * @param {string|HTMLElement|false} trigger\n\t * @return {Promise}\n\t */\n\tafterFetch(url, TransitionClass, entry, trigger) {\n\t\tthis.currentLocation = url\n\t\tthis.popTarget = this.currentLocation.href\n\n\t\treturn new Promise((resolve) => {\n\t\t\tentry.renderer.update()\n\n\t\t\tE.emit('NAVIGATE_IN', {\n\t\t\t\tfrom: this.currentCacheEntry,\n\t\t\t\tto: entry,\n\t\t\t\ttrigger\n\t\t\t})\n\n\t\t\tif (this.reloadJsFilter) {\n\t\t\t\tthis.loadScripts(entry.scripts)\n\t\t\t}\n\n\t\t\tif (this.reloadCssFilter) {\n\t\t\t\tthis.loadStyles(entry.styles)\n\t\t\t}\n\n\t\t\t// If the fetched url had a redirect chain, then replace the history to reflect the final resolved URL\n\t\t\tif (trigger !== 'popstate' && url.href !== entry.finalUrl) {\n\t\t\t\twindow.history.replaceState({}, '', entry.finalUrl)\n\t\t\t}\n\n\t\t\tentry.renderer.enter(TransitionClass, trigger)\n\t\t\t\t.then(() => {\n\t\t\t\t\tE.emit('NAVIGATE_END', {\n\t\t\t\t\t\tfrom: this.currentCacheEntry,\n\t\t\t\t\t\tto: entry,\n\t\t\t\t\t\ttrigger\n\t\t\t\t\t})\n\n\t\t\t\t\tthis.currentCacheEntry = entry\n\t\t\t\t\tthis.isTransitioning = false\n\t\t\t\t\tthis.isPopping = false\n\t\t\t\t\tresolve()\n\t\t\t\t})\n\t\t})\n\t}\n\n\t/**\n\t * Load up scripts from the target page if needed\n\t *\n\t * @param {HTMLElement[]} cachedScripts\n\t */\n\tloadScripts(cachedScripts) {\n\t\tconst newScripts = [...cachedScripts]\n\t\tconst currentScripts = Array.from(document.querySelectorAll('script')).filter(this.reloadJsFilter)\n\n\t\t// loop through all new scripts\n\t\tfor (let i = 0; i < currentScripts.length; i++) {\n\t\t\tfor (let n = 0; n < newScripts.length; n++) {\n\t\t\t\tif (currentScripts[i].outerHTML === newScripts[n].outerHTML) {\n\t\t\t\t\treloadElement(currentScripts[i], 'SCRIPT')\n\t\t\t\t\tnewScripts.splice(n, 1)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tfor (const script of newScripts) {\n\t\t\tappendElement(script, 'SCRIPT')\n\t\t}\n\t}\n\n\t/**\n\t * Load up styles from the target page if needed\n\t *\n\t * @param {Array} cachedStyles\n\t */\n\tloadStyles(cachedStyles) {\n\t\tconst currentStyles = Array.from(document.querySelectorAll('link[rel=\"stylesheet\"]')).filter(this.reloadCssFilter)\n\t\tconst currentInlineStyles = Array.from(document.querySelectorAll('style')).filter(this.reloadCssFilter)\n\n\t\tconst newInlineStyles = cachedStyles.filter(el => {\n\t\t\t// no el.href, assume it's an inline style\n\t\t\tif (!el.href) {\n\t\t\t\treturn true\n\t\t\t} else if (!currentStyles.find((link) => link.href === el.href)) {\n\t\t\t\tdocument.body.append(el)\n\t\t\t\treturn false\n\t\t\t}\n\t\t})\n\n\t\t// loop through all new inline styles\n\t\tfor (let i = 0; i < currentInlineStyles.length; i++) {\n\t\t\tfor (let n = 0; n < newInlineStyles.length; n++) {\n\t\t\t\tif (currentInlineStyles[i].outerHTML === newInlineStyles[n].outerHTML) {\n\t\t\t\t\treloadElement(currentInlineStyles[i], 'STYLE')\n\t\t\t\t\tnewInlineStyles.splice(n, 1)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tfor (const style of newInlineStyles) {\n\t\t\tappendElement(style, 'STYLE')\n\t\t}\n\t}\n\n\t/**\n\t * @private\n\t * @param {string} links\n\t */\n\tattachEvents(links) {\n\t\tE.delegate('click', links, this.onClick)\n\t\tE.on('popstate', window, this.onPopstate)\n\n\t\tif (this.enablePrefetch) {\n\t\t\tE.delegate('mouseenter focus', links, this.onPrefetch)\n\t\t}\n\t}\n\n\t/**\n\t * @private\n\t * @param {MouseEvent} e\n\t */\n\tonClick = (e) => {\n\t\tif (!(e.metaKey || e.ctrlKey)) {\n\t\t\tconst target = processUrl(e.currentTarget.href)\n\t\t\tthis.currentLocation = processUrl(window.location.href)\n\n\t\t\tif (this.currentLocation.host !== target.host) {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// the target is a new URL, or is removing the hash from the current URL\n\t\t\tif (this.currentLocation.href !== target.href || (this.currentLocation.hasHash && !target.hasHash)) {\n\t\t\t\te.preventDefault()\n\t\t\t\t// noinspection JSIgnoredPromiseFromCall\n\t\t\t\tthis.navigateTo(target.raw, e.currentTarget.dataset.transition || false, e.currentTarget).catch(err => console.warn(err))\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// a click to the current URL was detected\n\t\t\tif (!this.currentLocation.hasHash && !target.hasHash) {\n\t\t\t\te.preventDefault()\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * @private\n\t * @return {void|boolean}\n\t */\n\tonPopstate = () => {\n\t\t// don't trigger for on-page anchors\n\t\tif (window.location.pathname === this.currentLocation.pathname && !this.isPopping) {\n\t\t\treturn false\n\t\t}\n\n\t\tif (!this.allowInterruption && (this.isTransitioning || this.isPopping)) {\n\t\t\t// overwrite history state with current page if currently navigating\n\t\t\twindow.history.pushState({}, '', this.popTarget)\n\t\t\tconsole.warn(IN_PROGRESS)\n\t\t\treturn false\n\t\t}\n\n\t\tif (!this.isPopping) {\n\t\t\tthis.popTarget = window.location.href\n\t\t}\n\n\t\tthis.isPopping = true\n\n\t\t// noinspection JSIgnoredPromiseFromCall\n\t\tthis.navigateTo(window.location.href, false, 'popstate')\n\t}\n\n\t/**\n\t * @private\n\t * @param {MouseEvent} e\n\t */\n\tonPrefetch = (e) => {\n\t\tconst target = processUrl(e.currentTarget.href)\n\n\t\tif (this.currentLocation.host !== target.host) {\n\t\t\treturn\n\t\t}\n\n\t\tthis.preload(e.currentTarget.href, false)\n\t}\n\n\t/**\n\t * @private\n\t * @param {string} url\n\t * @param {boolean} [runFallback]\n\t * @return {Promise<{html: Document, url: string}>}\n\t */\n\tfetch(url, runFallback = true) {\n\t\t// If Taxi is currently performing a fetch for the given URL, return that instead of starting a new request\n\t\tif (this.activePromises.has(url)) {\n\t\t\treturn this.activePromises.get(url)\n\t\t}\n\n\t\tconst request = new Promise((resolve, reject) => {\n\t\t\tlet resolvedUrl\n\n\t\t\tfetch(url, {\n\t\t\t\tmode: 'same-origin',\n\t\t\t\tmethod: 'GET',\n\t\t\t\theaders: { 'X-Requested-With': 'Taxi' },\n\t\t\t\tcredentials: 'same-origin'\n\t\t\t})\n\t\t\t\t.then((response) => {\n\t\t\t\t\tif (!response.ok) {\n\t\t\t\t\t\treject('Taxi encountered a non 2xx HTTP status code')\n\n\t\t\t\t\t\tif (runFallback) {\n\t\t\t\t\t\t\twindow.location.href = url\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tresolvedUrl = response.url\n\n\t\t\t\t\treturn response.text()\n\t\t\t\t})\n\t\t\t\t.then((htmlString) => {\n\t\t\t\t\tresolve({ html: parseDom(htmlString), url: resolvedUrl })\n\t\t\t\t})\n\t\t\t\t.catch((err) => {\n\t\t\t\t\treject(err)\n\n\t\t\t\t\tif (runFallback) {\n\t\t\t\t\t\twindow.location.href = url\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\t.finally(() => {\n\t\t\t\t\tthis.activePromises.delete(url)\n\t\t\t\t})\n\t\t})\n\n\t\tthis.activePromises.set(url, request)\n\n\t\treturn request\n\t}\n\n\t/**\n\t * @private\n\t * @param {string|false} transition\n\t * @return {Transition|function}\n\t */\n\tchooseTransition(transition) {\n\t\tif (transition) {\n\t\t\treturn this.transitions[transition]\n\t\t}\n\n\t\tconst routeTransition = this.router?.findMatch(this.currentLocation, this.targetLocation)\n\n\t\tif (routeTransition) {\n\t\t\treturn this.transitions[routeTransition]\n\t\t}\n\n\t\treturn this.defaultTransition\n\t}\n\n\t/**\n\t * @private\n\t * @param {Document|Node} page\n\t * @param {string} url\n\t * @return {CacheEntry}\n\t */\n\tcreateCacheEntry(page, url) {\n\t\tconst content = page.querySelector('[data-taxi-view]')\n\t\tconst Renderer = content.dataset.taxiView.length ? this.renderers[content.dataset.taxiView] : this.defaultRenderer\n\n\t\tif (!Renderer) {\n\t\t\tconsole.warn(`The Renderer \"${content.dataset.taxiView}\" was set in the data-taxi-view of the requested page, but not registered in Taxi.`)\n\t\t}\n\n\t\treturn {\n\t\t\tpage,\n\t\t\tcontent,\n\t\t\tfinalUrl: url,\n\t\t\tskipCache: content.hasAttribute('data-taxi-nocache'),\n\t\t\tscripts: this.reloadJsFilter ? Array.from(page.querySelectorAll('script')).filter(this.reloadJsFilter) : [],\n\t\t\tstyles: this.reloadCssFilter ? Array.from(page.querySelectorAll('link[rel=\"stylesheet\"], style')).filter(this.reloadCssFilter) : [],\n\t\t\ttitle: page.title,\n\t\t\trenderer: new Renderer({\n\t\t\t\twrapper: this.wrapper,\n\t\t\t\ttitle: page.title,\n\t\t\t\tcontent,\n\t\t\t\tpage\n\t\t\t})\n\t\t}\n\t}\n}\n"],"names":["parser","DOMParser","processUrl","url","details","URL","window","location","origin","normalized","hash","length","replace","hasHash","pathname","host","raw","href","reloadElement","node","elementType","parentNode","replaceChild","duplicateElement","appendElement","tagName","document","head","body","appendChild","replacement","createElement","k","attributes","attr","setAttribute","nodeName","nodeValue","innerHTML","Transition","this","wrapper","leave","props","Promise","resolve","_this","onLeave","done","enter","_this2","onEnter","Renderer","page","title","_contentString","content","outerHTML","_DOM","lastElementChild","onEnterCompleted","onLeaveCompleted","initialLoad","update","firstElementChild","createDom","remove","transition","trigger","to","then","removeOldContent","from","RouteStore","data","Map","regexCache","add","fromPattern","toPattern","has","set","RegExp","get","findMatch","currentUrl","nextUrl","potentialMatches","match","IN_PROGRESS","Core","parameters","isTransitioning","currentCacheEntry","cache","activePromises","onClick","e","metaKey","ctrlKey","target","currentTarget","currentLocation","preventDefault","navigateTo","dataset","err","console","warn","onPopstate","isPopping","allowInterruption","popTarget","history","pushState","onPrefetch","preload","links","bypassCache","enablePrefetch","renderers","transitions","default","reloadJsFilter","element","undefined","taxiReload","reloadCssFilter","defaultRenderer","defaultTransition","querySelector","attachEvents","createCacheEntry","cloneNode","renderer","setDefaultRenderer","setDefaultTransition","addRoute","router","preloadAssets","fetch","response","html","updateCache","key","clearCache","reject","_this3","targetLocation","navigationPromise","TransitionClass","chooseTransition","skipCache","fetched","beforeFetch","afterFetch","Error","on","event","callback","E","off","emit","_this4","entry","_this5","loadScripts","scripts","loadStyles","styles","finalUrl","replaceState","cachedScripts","newScripts","currentScripts","Array","querySelectorAll","filter","i","n","splice","cachedStyles","currentStyles","currentInlineStyles","newInlineStyles","el","find","link","append","delegate","runFallback","request","resolvedUrl","mode","method","headers","credentials","ok","text","htmlString","parseFromString","_this6","routeTransition","_this$router","taxiView","hasAttribute"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"taxi.js","sources":["../src/helpers.js","../src/Transition.js","../src/Renderer.js","../src/RouteStore.js","../src/Core.js"],"sourcesContent":["const parser = new DOMParser()\n\n/**\n * Parse a HTML string into a proper Document.\n *\n * @param {string|Document} html\n * @return {Document|*}\n */\nexport function parseDom(html) {\n\treturn typeof html === 'string' ? parser.parseFromString(html, 'text/html') : html\n}\n\n/**\n * Extract details from a given URL string. Assumed to be on the current TLD.\n *\n * @param {string} url\n * @return {{raw: string, href: string, host: string, search: string, hasHash: boolean, pathname: string}}\n */\nexport function processUrl(url) {\n\tconst details = new URL(url, window.location.origin)\n\tconst normalized = details.hash.length ? url.replace(details.hash, '') : null\n\n\treturn {\n\t\thasHash: details.hash.length > 0,\n\t\tpathname: details.pathname,\n\t\thost: details.host,\n\t\tsearch: details.search,\n\t\traw: url,\n\t\thref: normalized || details.href\n\t}\n}\n\n/**\n * Reloads a provided script/stylesheet by replacing with itself.\n *\n * @param {HTMLElement|HTMLScriptElement|HTMLStyleElement} node\n * @param {string} elementType - 'SCRIPT' or 'STYLE'\n */\nexport function reloadElement(node, elementType) {\n\tnode.parentNode.replaceChild(duplicateElement(node, elementType), node)\n}\n\n/**\n * Loads a provided script/stylesheet by appending a clone to the current document.\n *\n * @param {HTMLElement|HTMLStyleElement} node\n * @param {string} elementType - 'SCRIPT' or 'STYLE'\n */\nexport function appendElement(node, elementType) {\n\tconst target = node.parentNode.tagName === 'HEAD' ? document.head : document.body\n\ttarget.appendChild(duplicateElement(node, elementType))\n}\n\n/**\n * Creates a clone of a given HTMLElement or HTMLStyleElement\n *\n * @param {HTMLElement|HTMLStyleElement} node\n * @param {string} elementType - 'SCRIPT' or 'STYLE'\n * @return {HTMLElement|HTMLStyleElement}\n */\nexport function duplicateElement(node, elementType) {\n\tconst replacement = document.createElement(elementType)\n\n\tfor (let k = 0; k < node.attributes.length; k++) {\n\t\tconst attr = node.attributes[k]\n\t\treplacement.setAttribute(attr.nodeName, attr.nodeValue)\n\t}\n\n\t// Inline Script or Style\n\tif (node.innerHTML) {\n\t\treplacement.innerHTML = node.innerHTML\n\t}\n\n\treturn replacement\n}\n","export default class Transition {\n\t/**\n\t * @param {{wrapper: HTMLElement}} props\n\t */\n\tconstructor({ wrapper }) {\n\t\tthis.wrapper = wrapper\n\t}\n\n\t/**\n\t * @param {{ from: HTMLElement|Element, trigger: string|HTMLElement|false }} props\n\t * @return {Promise}\n\t */\n\tleave(props) {\n\t\treturn new Promise((resolve) => {\n\t\t\tthis.onLeave({ ...props, done: resolve })\n\t\t})\n\t}\n\n\t/**\n\t * @param {{ to: HTMLElement|Element, trigger: string|HTMLElement|false }} props\n\t * @return {Promise}\n\t */\n\tenter(props) {\n\t\treturn new Promise((resolve) => {\n\t\t\tthis.onEnter({ ...props, done: resolve })\n\t\t})\n\t}\n\n\t/**\n\t * Handle the transition leaving the previous page.\n\t * @param {{from: HTMLElement|Element, trigger: string|HTMLElement|false, done: function}} props\n\t */\n\tonLeave({ from, trigger, done }) {\n\t\tdone()\n\t}\n\n\t/**\n\t * Handle the transition entering the next page.\n\t * @param {{to: HTMLElement|Element, trigger: string|HTMLElement|false, done: function}} props\n\t */\n\tonEnter({ to, trigger, done }) {\n\t\tdone()\n\t}\n}\n","import Transition from \"./Transition\"\n\nexport default class Renderer {\n\t/**\n\t * @param {{content: HTMLElement|Element, page: Document|Node, title: string, wrapper: Element}} props\n\t */\n\tconstructor({ content, page, title, wrapper }) {\n\t\tthis._contentString = content.outerHTML\n\t\tthis._DOM = null\n\t\tthis.page = page\n\t\tthis.title = title\n\t\tthis.wrapper = wrapper\n\t\tthis.content = this.wrapper.lastElementChild\n\t}\n\n\tonEnter() {\n\n\t}\n\n\tonEnterCompleted() {\n\n\t}\n\n\tonLeave() {\n\n\t}\n\n\tonLeaveCompleted() {\n\n\t}\n\n\tinitialLoad() {\n\t\tthis.onEnter()\n\t\tthis.onEnterCompleted()\n\t}\n\n\tupdate() {\n\t\tdocument.title = this.title\n\t\tthis.wrapper.appendChild(this._DOM.firstElementChild)\n\t\tthis.content = this.wrapper.lastElementChild\n\t\tthis._DOM = null\n\t}\n\n\tcreateDom() {\n\t\tif (!this._DOM) {\n\t\t\tthis._DOM = document.createElement('div')\n\t\t\tthis._DOM.innerHTML = this._contentString\n\t\t}\n\t}\n\n\tremove() {\n\t\tthis.wrapper.firstElementChild.remove()\n\t}\n\n\t/**\n\t * Called when transitioning into the current page.\n\t * @param {Transition} transition\n\t * @param {string|HTMLElement|false} trigger\n\t * @return {Promise}\n\t */\n\tenter(transition, trigger) {\n\t\treturn new Promise((resolve) => {\n\t\t\tthis.onEnter()\n\n\t\t\ttransition.enter({ trigger, to: this.content })\n\t\t\t\t.then(() => {\n\t\t\t\t\tthis.onEnterCompleted()\n\t\t\t\t\tresolve()\n\t\t\t\t})\n\t\t})\n\t}\n\n\t/**\n\t * Called when transitioning away from the current page.\n\t * @param {Transition} transition\n\t * @param {string|HTMLElement|false} trigger\n\t * @param {boolean} removeOldContent\n\t * @return {Promise}\n\t */\n\tleave(transition, trigger, removeOldContent) {\n\t\treturn new Promise((resolve) => {\n\t\t\tthis.onLeave()\n\n\t\t\ttransition.leave({ trigger, from: this.content })\n\t\t\t\t.then(() => {\n\t\t\t\t\tif (removeOldContent) {\n\t\t\t\t\t\tthis.remove()\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.onLeaveCompleted()\n\t\t\t\t\tresolve()\n\t\t\t\t})\n\t\t})\n\t}\n}\n","export default class RouteStore {\n\t/**\n\t * @type {Map>}\n\t */\n\tdata = new Map()\n\n\t/**\n\t * @type {Map}\n\t */\n\tregexCache = new Map()\n\n\t/**\n\t *\n\t * @param {string} fromPattern\n\t * @param {string} toPattern\n\t * @param {string} transition\n\t */\n\tadd(fromPattern, toPattern, transition) {\n\t\tif (!this.data.has(fromPattern)) {\n\t\t\tthis.data.set(fromPattern, new Map())\n\t\t\tthis.regexCache.set(fromPattern, new RegExp(`^${fromPattern}$`))\n\t\t}\n\n\t\tthis.data.get(fromPattern).set(toPattern, transition)\n\t\tthis.regexCache.set(toPattern, new RegExp(`^${toPattern}$`))\n\t}\n\n\t/**\n\t *\n\t * @param {{ raw: string, href: string, hasHash: boolean, pathname: string }} currentUrl\n\t * @param {{ raw: string, href: string, hasHash: boolean, pathname: string }} nextUrl\n\t * @return {string|null}\n\t */\n\tfindMatch(currentUrl, nextUrl) {\n\t\t// Loop through all from patterns\n\t\tfor (const [fromPattern, potentialMatches] of this.data) {\n\t\t\t// If we have a match\n\t\t\tif (currentUrl.pathname.match(this.regexCache.get(fromPattern))) {\n\t\t\t\t// loop through all associated to patterns\n\t\t\t\tfor (const [toPattern, transition] of potentialMatches) {\n\t\t\t\t\t// If we find a match, return it\n\t\t\t\t\tif (nextUrl.pathname.match(this.regexCache.get(toPattern))) {\n\t\t\t\t\t\treturn transition\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\treturn null\n\t}\n}\n","import E from '@unseenco/e'\nimport { appendElement, parseDom, processUrl, reloadElement } from './helpers'\nimport Transition from './Transition'\nimport Renderer from './Renderer'\nimport RouteStore from './RouteStore'\n\nconst IN_PROGRESS = 'A transition is currently in progress'\n\n/**\n * @typedef CacheEntry\n * @type {object}\n * @property {typeof Renderer|Renderer} renderer\n * @property {Document|Node} page\n * @property {array} scripts\n * @property {HTMLLinkElement[]} styles\n * @property {string} finalUrl\n * @property {boolean} skipCache\n * @property {string} title\n * @property {HTMLElement|Element} content\n */\n\nexport default class Core {\n\tisTransitioning = false\n\n\t/**\n\t * @type {CacheEntry|null}\n\t */\n\tcurrentCacheEntry = null\n\n\t/**\n\t * @type {Map}\n\t */\n\tcache = new Map()\n\n\t/**\n\t * @private\n\t * @type {Map}\n\t */\n\tactivePromises = new Map()\n\n\t/**\n\t * @param {{\n\t * \t\tlinks?: string,\n\t * \t\tremoveOldContent?: boolean,\n\t * \t\tallowInterruption?: boolean,\n\t * \t\tbypassCache?: boolean,\n\t * \t\tenablePrefetch?: boolean,\n\t * \t\trenderers?: Object.,\n\t * \t\ttransitions?: Object.,\n\t * \t\treloadJsFilter?: boolean|function(HTMLElement): boolean,\n\t * \t\treloadCssFilter?: boolean|function(HTMLLinkElement): boolean\n\t * }} parameters\n\t */\n\tconstructor(parameters = {}) {\n\t\tconst {\n\t\t\tlinks = 'a:not([target]):not([href^=\\\\#]):not([data-taxi-ignore])',\n\t\t\tremoveOldContent = true,\n\t\t\tallowInterruption = false,\n\t\t\tbypassCache = false,\n\t\t\tenablePrefetch = true,\n\t\t\trenderers = {\n\t\t\t\tdefault: Renderer\n\t\t\t},\n\t\t\ttransitions = {\n\t\t\t\tdefault: Transition\n\t\t\t},\n\t\t\treloadJsFilter = (element) => element.dataset.taxiReload !== undefined,\n\t\t\treloadCssFilter = (element) => true //element.dataset.taxiReload !== undefined\n\t\t} = parameters\n\n\t\tthis.renderers = renderers\n\t\tthis.transitions = transitions\n\t\tthis.defaultRenderer = this.renderers.default || Renderer\n\t\tthis.defaultTransition = this.transitions.default || Transition\n\t\tthis.wrapper = document.querySelector('[data-taxi]')\n\t\tthis.reloadJsFilter = reloadJsFilter\n\t\tthis.reloadCssFilter = reloadCssFilter\n\t\tthis.removeOldContent = removeOldContent\n\t\tthis.allowInterruption = allowInterruption\n\t\tthis.bypassCache = bypassCache\n\t\tthis.enablePrefetch = enablePrefetch\n\t\tthis.cache = new Map()\n\t\tthis.isPopping = false\n\n\t\t// Add delegated link events\n\t\tthis.attachEvents(links)\n\n\t\tthis.currentLocation = processUrl(window.location.href)\n\n\t\t// as this is the initial page load, prime this page into the cache\n\t\tthis.cache.set(this.currentLocation.href, this.createCacheEntry(document.cloneNode(true), window.location.href))\n\n\t\t// fire the current Renderer enter methods\n\t\tthis.currentCacheEntry = this.cache.get(this.currentLocation.href)\n\t\tthis.currentCacheEntry.renderer.initialLoad()\n\t}\n\n\t/**\n\t * @param {string} renderer\n\t */\n\tsetDefaultRenderer(renderer) {\n\t\tthis.defaultRenderer = this.renderers[renderer]\n\t}\n\n\t/**\n\t * @param {string} transition\n\t */\n\tsetDefaultTransition(transition) {\n\t\tthis.defaultTransition = this.transitions[transition]\n\t}\n\n\t/**\n\t * Registers a route into the RouteStore\n\t *\n\t * @param {string} fromPattern\n\t * @param {string} toPattern\n\t * @param {string} transition\n\t */\n\taddRoute(fromPattern, toPattern, transition) {\n\t\tif (!this.router) {\n\t\t\tthis.router = new RouteStore()\n\t\t}\n\n\t\tthis.router.add(fromPattern, toPattern, transition)\n\t}\n\n\t/**\n\t * Prime the cache for a given URL\n\t *\n\t * @param {string} url\n\t * @param {boolean} [preloadAssets]\n\t * @return {Promise}\n\t */\n\tpreload(url, preloadAssets = false) {\n\t\t// convert relative URLs to absolute\n\t\turl = processUrl(url).href\n\n\t\tif (!this.cache.has(url)) {\n\t\t\treturn this.fetch(url, false)\n\t\t\t\t.then(async (response) => {\n\t\t\t\t\tthis.cache.set(url, this.createCacheEntry(response.html, response.url))\n\n\t\t\t\t\tif (preloadAssets) {\n\t\t\t\t\t\tthis.cache.get(url).renderer.createDom()\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\t.catch(err => console.warn(err))\n\t\t}\n\n\t\treturn Promise.resolve()\n\t}\n\n\t/**\n\t * Updates the HTML cache for a given URL.\n\t * If no URL is passed, then cache for the current page is updated.\n\t * Useful when adding/removing content via AJAX such as a search page or infinite loader.\n\t *\n\t * @param {string} [url]\n\t */\n\tupdateCache(url) {\n\t\tconst key = processUrl(url || window.location.href).href\n\n\t\tif (this.cache.has(key)) {\n\t\t\tthis.cache.delete(key)\n\t\t}\n\n\t\tthis.cache.set(key, this.createCacheEntry(document.cloneNode(true), key))\n\t}\n\n\t/**\n\t * Clears the cache for a given URL.\n\t * If no URL is passed, then cache for the current page is cleared.\n\t *\n\t * @param {string} [url]\n\t */\n\tclearCache(url) {\n\t\tconst key = processUrl(url || window.location.href).href\n\n\t\tif (this.cache.has(key)) {\n\t\t\tthis.cache.delete(key)\n\t\t}\n\t}\n\n\t/**\n\t * @param {string} url\n\t * @param {string|false} [transition]\n\t * @param {string|false|HTMLElement} [trigger]\n\t * @return {Promise}\n\t */\n\tnavigateTo(url, transition = false, trigger = false) {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\t// Don't allow multiple navigations to occur at once\n\t\t\tif (!this.allowInterruption && this.isTransitioning) {\n\t\t\t\treject(new Error(IN_PROGRESS))\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tthis.isTransitioning = true\n\t\t\tthis.isPopping = true\n\t\t\tthis.targetLocation = processUrl(url)\n\t\t\tthis.popTarget = window.location.href\n\n\t\t\tconst TransitionClass = new (this.chooseTransition(transition))({ wrapper: this.wrapper })\n\n\t\t\tlet navigationPromise\n\n\t\t\tif (this.bypassCache || !this.cache.has(this.targetLocation.href) || this.cache.get(this.targetLocation.href).skipCache) {\n\t\t\t\tconst fetched = this.fetch(this.targetLocation.href)\n\t\t\t\t\t.then((response) => {\n\t\t\t\t\t\tthis.cache.set(this.targetLocation.href, this.createCacheEntry(response.html, response.url))\n\t\t\t\t\t\tthis.cache.get(this.targetLocation.href).renderer.createDom()\n\t\t\t\t\t})\n\t\t\t\t\t.catch(err => {\n\t\t\t\t\t\t// we encountered a 4** or 5** error, redirect to the requested URL\n\t\t\t\t\t\twindow.location.href = url\n\t\t\t\t\t})\n\n\t\t\t\tnavigationPromise = this.beforeFetch(this.targetLocation, TransitionClass, trigger)\n\t\t\t\t\t.then(async () => {\n\t\t\t\t\t\treturn fetched.then(async () => {\n\t\t\t\t\t\t\treturn await this.afterFetch(this.targetLocation, TransitionClass, this.cache.get(this.targetLocation.href), trigger)\n\t\t\t\t\t\t})\n\t\t\t\t\t})\n\t\t\t} else {\n\t\t\t\tthis.cache.get(this.targetLocation.href).renderer.createDom()\n\n\t\t\t\tnavigationPromise = this.beforeFetch(this.targetLocation, TransitionClass, trigger)\n\t\t\t\t\t.then(async () => {\n\t\t\t\t\t\treturn await this.afterFetch(this.targetLocation, TransitionClass, this.cache.get(this.targetLocation.href), trigger)\n\t\t\t\t\t})\n\t\t\t}\n\n\t\t\tnavigationPromise.then(() => {\n\t\t\t\tresolve()\n\t\t\t})\n\t\t})\n\t}\n\n\t/**\n\t * Add an event listener.\n\t * @param {string} event\n\t * @param {any} callback\n\t */\n\ton(event, callback) {\n\t\tE.on(event, callback)\n\t}\n\n\t/**\n\t * Remove an event listener.\n\t * @param {string} event\n\t * @param {any} [callback]\n\t */\n\toff(event, callback) {\n\t\tE.off(event, callback)\n\t}\n\n\t/**\n\t * @private\n\t * @param {{ raw: string, href: string, hasHash: boolean, pathname: string }} url\n\t * @param {Transition} TransitionClass\n\t * @param {string|HTMLElement|false} trigger\n\t * @return {Promise}\n\t */\n\tbeforeFetch(url, TransitionClass, trigger) {\n\t\tE.emit('NAVIGATE_OUT', {\n\t\t\tfrom: this.currentCacheEntry,\n\t\t\ttrigger\n\t\t})\n\n\t\treturn new Promise((resolve) => {\n\t\t\tthis.currentCacheEntry.renderer.leave(TransitionClass, trigger, this.removeOldContent)\n\t\t\t\t.then(() => {\n\t\t\t\t\tif (trigger !== 'popstate') {\n\t\t\t\t\t\twindow.history.pushState({}, '', url.raw)\n\t\t\t\t\t}\n\n\t\t\t\t\tresolve()\n\t\t\t\t})\n\t\t})\n\t}\n\n\t/**\n\t * @private\n\t * @param {{ raw: string, href: string, host: string, hasHash: boolean, pathname: string }} url\n\t * @param {Transition} TransitionClass\n\t * @param {CacheEntry} entry\n\t * @param {string|HTMLElement|false} trigger\n\t * @return {Promise}\n\t */\n\tafterFetch(url, TransitionClass, entry, trigger) {\n\t\tthis.currentLocation = url\n\t\tthis.popTarget = this.currentLocation.href\n\n\t\treturn new Promise((resolve) => {\n\t\t\tentry.renderer.update()\n\n\t\t\tE.emit('NAVIGATE_IN', {\n\t\t\t\tfrom: this.currentCacheEntry,\n\t\t\t\tto: entry,\n\t\t\t\ttrigger\n\t\t\t})\n\n\t\t\tif (this.reloadJsFilter) {\n\t\t\t\tthis.loadScripts(entry.scripts)\n\t\t\t}\n\n\t\t\tif (this.reloadCssFilter) {\n\t\t\t\tthis.loadStyles(entry.styles)\n\t\t\t}\n\n\t\t\t// If the fetched url had a redirect chain, then replace the history to reflect the final resolved URL\n\t\t\tif (trigger !== 'popstate' && url.href !== entry.finalUrl) {\n\t\t\t\twindow.history.replaceState({}, '', entry.finalUrl)\n\t\t\t}\n\n\t\t\tentry.renderer.enter(TransitionClass, trigger)\n\t\t\t\t.then(() => {\n\t\t\t\t\tE.emit('NAVIGATE_END', {\n\t\t\t\t\t\tfrom: this.currentCacheEntry,\n\t\t\t\t\t\tto: entry,\n\t\t\t\t\t\ttrigger\n\t\t\t\t\t})\n\n\t\t\t\t\tthis.currentCacheEntry = entry\n\t\t\t\t\tthis.isTransitioning = false\n\t\t\t\t\tthis.isPopping = false\n\t\t\t\t\tresolve()\n\t\t\t\t})\n\t\t})\n\t}\n\n\t/**\n\t * Load up scripts from the target page if needed\n\t *\n\t * @param {HTMLElement[]} cachedScripts\n\t */\n\tloadScripts(cachedScripts) {\n\t\tconst newScripts = [...cachedScripts]\n\t\tconst currentScripts = Array.from(document.querySelectorAll('script')).filter(this.reloadJsFilter)\n\n\t\t// loop through all new scripts\n\t\tfor (let i = 0; i < currentScripts.length; i++) {\n\t\t\tfor (let n = 0; n < newScripts.length; n++) {\n\t\t\t\tif (currentScripts[i].outerHTML === newScripts[n].outerHTML) {\n\t\t\t\t\treloadElement(currentScripts[i], 'SCRIPT')\n\t\t\t\t\tnewScripts.splice(n, 1)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tfor (const script of newScripts) {\n\t\t\tappendElement(script, 'SCRIPT')\n\t\t}\n\t}\n\n\t/**\n\t * Load up styles from the target page if needed\n\t *\n\t * @param {Array} cachedStyles\n\t */\n\tloadStyles(cachedStyles) {\n\t\tconst currentStyles = Array.from(document.querySelectorAll('link[rel=\"stylesheet\"]')).filter(this.reloadCssFilter)\n\t\tconst currentInlineStyles = Array.from(document.querySelectorAll('style')).filter(this.reloadCssFilter)\n\n\t\tconst newInlineStyles = cachedStyles.filter(el => {\n\t\t\t// no el.href, assume it's an inline style\n\t\t\tif (!el.href) {\n\t\t\t\treturn true\n\t\t\t} else if (!currentStyles.find((link) => link.href === el.href)) {\n\t\t\t\tdocument.body.append(el)\n\t\t\t\treturn false\n\t\t\t}\n\t\t})\n\n\t\t// loop through all new inline styles\n\t\tfor (let i = 0; i < currentInlineStyles.length; i++) {\n\t\t\tfor (let n = 0; n < newInlineStyles.length; n++) {\n\t\t\t\tif (currentInlineStyles[i].outerHTML === newInlineStyles[n].outerHTML) {\n\t\t\t\t\treloadElement(currentInlineStyles[i], 'STYLE')\n\t\t\t\t\tnewInlineStyles.splice(n, 1)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tfor (const style of newInlineStyles) {\n\t\t\tappendElement(style, 'STYLE')\n\t\t}\n\t}\n\n\t/**\n\t * @private\n\t * @param {string} links\n\t */\n\tattachEvents(links) {\n\t\tE.delegate('click', links, this.onClick)\n\t\tE.on('popstate', window, this.onPopstate)\n\n\t\tif (this.enablePrefetch) {\n\t\t\tE.delegate('mouseenter focus', links, this.onPrefetch)\n\t\t}\n\t}\n\n\t/**\n\t * @private\n\t * @param {MouseEvent} e\n\t */\n\tonClick = (e) => {\n\t\tif (!(e.metaKey || e.ctrlKey)) {\n\t\t\tconst target = processUrl(e.currentTarget.href)\n\t\t\tthis.currentLocation = processUrl(window.location.href)\n\n\t\t\tif (this.currentLocation.host !== target.host) {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// the target is a new URL, or is removing the hash from the current URL\n\t\t\tif (this.currentLocation.href !== target.href || (this.currentLocation.hasHash && !target.hasHash)) {\n\t\t\t\te.preventDefault()\n\t\t\t\t// noinspection JSIgnoredPromiseFromCall\n\t\t\t\tthis.navigateTo(target.raw, e.currentTarget.dataset.transition || false, e.currentTarget).catch(err => console.warn(err))\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// a click to the current URL was detected\n\t\t\tif (!this.currentLocation.hasHash && !target.hasHash) {\n\t\t\t\te.preventDefault()\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * @private\n\t * @return {void|boolean}\n\t */\n\tonPopstate = () => {\n\t\t// don't trigger for on-page anchors\n\t\tif (\n\t\t\twindow.location.pathname === this.currentLocation.pathname\n\t\t\t&& window.location.search === this.currentLocation.search\n\t\t\t&& !this.isPopping\n\t\t) {\n\t\t\treturn false\n\t\t}\n\n\t\tif (!this.allowInterruption && (this.isTransitioning || this.isPopping)) {\n\t\t\t// overwrite history state with current page if currently navigating\n\t\t\twindow.history.pushState({}, '', this.popTarget)\n\t\t\tconsole.warn(IN_PROGRESS)\n\t\t\treturn false\n\t\t}\n\n\t\tif (!this.isPopping) {\n\t\t\tthis.popTarget = window.location.href\n\t\t}\n\n\t\tthis.isPopping = true\n\n\t\t// noinspection JSIgnoredPromiseFromCall\n\t\tthis.navigateTo(window.location.href, false, 'popstate')\n\t}\n\n\t/**\n\t * @private\n\t * @param {MouseEvent} e\n\t */\n\tonPrefetch = (e) => {\n\t\tconst target = processUrl(e.currentTarget.href)\n\n\t\tif (this.currentLocation.host !== target.host) {\n\t\t\treturn\n\t\t}\n\n\t\tthis.preload(e.currentTarget.href, false)\n\t}\n\n\t/**\n\t * @private\n\t * @param {string} url\n\t * @param {boolean} [runFallback]\n\t * @return {Promise<{html: Document, url: string}>}\n\t */\n\tfetch(url, runFallback = true) {\n\t\t// If Taxi is currently performing a fetch for the given URL, return that instead of starting a new request\n\t\tif (this.activePromises.has(url)) {\n\t\t\treturn this.activePromises.get(url)\n\t\t}\n\n\t\tconst request = new Promise((resolve, reject) => {\n\t\t\tlet resolvedUrl\n\n\t\t\tfetch(url, {\n\t\t\t\tmode: 'same-origin',\n\t\t\t\tmethod: 'GET',\n\t\t\t\theaders: { 'X-Requested-With': 'Taxi' },\n\t\t\t\tcredentials: 'same-origin'\n\t\t\t})\n\t\t\t\t.then((response) => {\n\t\t\t\t\tif (!response.ok) {\n\t\t\t\t\t\treject('Taxi encountered a non 2xx HTTP status code')\n\n\t\t\t\t\t\tif (runFallback) {\n\t\t\t\t\t\t\twindow.location.href = url\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tresolvedUrl = response.url\n\n\t\t\t\t\treturn response.text()\n\t\t\t\t})\n\t\t\t\t.then((htmlString) => {\n\t\t\t\t\tresolve({ html: parseDom(htmlString), url: resolvedUrl })\n\t\t\t\t})\n\t\t\t\t.catch((err) => {\n\t\t\t\t\treject(err)\n\n\t\t\t\t\tif (runFallback) {\n\t\t\t\t\t\twindow.location.href = url\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\t.finally(() => {\n\t\t\t\t\tthis.activePromises.delete(url)\n\t\t\t\t})\n\t\t})\n\n\t\tthis.activePromises.set(url, request)\n\n\t\treturn request\n\t}\n\n\t/**\n\t * @private\n\t * @param {string|false} transition\n\t * @return {Transition|function}\n\t */\n\tchooseTransition(transition) {\n\t\tif (transition) {\n\t\t\treturn this.transitions[transition]\n\t\t}\n\n\t\tconst routeTransition = this.router?.findMatch(this.currentLocation, this.targetLocation)\n\n\t\tif (routeTransition) {\n\t\t\treturn this.transitions[routeTransition]\n\t\t}\n\n\t\treturn this.defaultTransition\n\t}\n\n\t/**\n\t * @private\n\t * @param {Document|Node} page\n\t * @param {string} url\n\t * @return {CacheEntry}\n\t */\n\tcreateCacheEntry(page, url) {\n\t\tconst content = page.querySelector('[data-taxi-view]')\n\t\tconst Renderer = content.dataset.taxiView.length ? this.renderers[content.dataset.taxiView] : this.defaultRenderer\n\n\t\tif (!Renderer) {\n\t\t\tconsole.warn(`The Renderer \"${content.dataset.taxiView}\" was set in the data-taxi-view of the requested page, but not registered in Taxi.`)\n\t\t}\n\n\t\treturn {\n\t\t\tpage,\n\t\t\tcontent,\n\t\t\tfinalUrl: url,\n\t\t\tskipCache: content.hasAttribute('data-taxi-nocache'),\n\t\t\tscripts: this.reloadJsFilter ? Array.from(page.querySelectorAll('script')).filter(this.reloadJsFilter) : [],\n\t\t\tstyles: this.reloadCssFilter ? Array.from(page.querySelectorAll('link[rel=\"stylesheet\"], style')).filter(this.reloadCssFilter) : [],\n\t\t\ttitle: page.title,\n\t\t\trenderer: new Renderer({\n\t\t\t\twrapper: this.wrapper,\n\t\t\t\ttitle: page.title,\n\t\t\t\tcontent,\n\t\t\t\tpage\n\t\t\t})\n\t\t}\n\t}\n}\n"],"names":["parser","DOMParser","processUrl","url","details","URL","window","location","origin","normalized","hash","length","replace","hasHash","pathname","host","search","raw","href","reloadElement","node","elementType","parentNode","replaceChild","duplicateElement","appendElement","tagName","document","head","body","appendChild","replacement","createElement","k","attributes","attr","setAttribute","nodeName","nodeValue","innerHTML","Transition","this","wrapper","leave","props","Promise","resolve","_this","onLeave","done","enter","_this2","onEnter","Renderer","page","title","_contentString","content","outerHTML","_DOM","lastElementChild","onEnterCompleted","onLeaveCompleted","initialLoad","update","firstElementChild","createDom","remove","transition","trigger","to","then","removeOldContent","from","RouteStore","data","Map","regexCache","add","fromPattern","toPattern","has","set","RegExp","get","findMatch","currentUrl","nextUrl","potentialMatches","match","IN_PROGRESS","Core","parameters","isTransitioning","currentCacheEntry","cache","activePromises","onClick","e","metaKey","ctrlKey","target","currentTarget","currentLocation","preventDefault","navigateTo","dataset","err","console","warn","onPopstate","isPopping","allowInterruption","popTarget","history","pushState","onPrefetch","preload","links","bypassCache","enablePrefetch","renderers","transitions","default","reloadJsFilter","element","undefined","taxiReload","reloadCssFilter","defaultRenderer","defaultTransition","querySelector","attachEvents","createCacheEntry","cloneNode","renderer","setDefaultRenderer","setDefaultTransition","addRoute","router","preloadAssets","fetch","response","html","updateCache","key","clearCache","reject","_this3","targetLocation","navigationPromise","TransitionClass","chooseTransition","skipCache","fetched","beforeFetch","afterFetch","Error","on","event","callback","E","off","emit","_this4","entry","_this5","loadScripts","scripts","loadStyles","styles","finalUrl","replaceState","cachedScripts","newScripts","currentScripts","Array","querySelectorAll","filter","i","n","splice","cachedStyles","currentStyles","currentInlineStyles","newInlineStyles","el","find","link","append","delegate","runFallback","request","resolvedUrl","mode","method","headers","credentials","ok","text","htmlString","parseFromString","_this6","routeTransition","_this$router","taxiView","hasAttribute"],"mappings":"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"} \ No newline at end of file diff --git a/dist/taxi.modern.js b/dist/taxi.modern.js index 74d7556..cd35716 100644 --- a/dist/taxi.modern.js +++ b/dist/taxi.modern.js @@ -1,2 +1,2 @@ -import t from"@unseenco/e";const e=new DOMParser;function r(t){const e=new URL(t,window.location.origin),r=e.hash.length?t.replace(e.hash,""):null;return{hasHash:e.hash.length>0,pathname:e.pathname,host:e.host,raw:t,href:r||e.href}}function i(t,e){t.parentNode.replaceChild(s(t,e),t)}function n(t,e){("HEAD"===t.parentNode.tagName?document.head:document.body).appendChild(s(t,e))}function s(t,e){const r=document.createElement(e);for(let e=0;e{this.onLeave(a({},t,{done:e}))})}enter(t){return new Promise(e=>{this.onEnter(a({},t,{done:e}))})}onLeave({done:t}){t()}onEnter({done:t}){t()}}class h{constructor({content:t,page:e,title:r,wrapper:i}){this._contentString=t.outerHTML,this._DOM=null,this.page=e,this.title=r,this.wrapper=i,this.content=this.wrapper.lastElementChild}onEnter(){}onEnterCompleted(){}onLeave(){}onLeaveCompleted(){}initialLoad(){this.onEnter(),this.onEnterCompleted()}update(){document.title=this.title,this.wrapper.appendChild(this._DOM.firstElementChild),this.content=this.wrapper.lastElementChild,this._DOM=null}createDom(){this._DOM||(this._DOM=document.createElement("div"),this._DOM.innerHTML=this._contentString)}remove(){this.wrapper.firstElementChild.remove()}enter(t,e){return new Promise(r=>{this.onEnter(),t.enter({trigger:e,to:this.content}).then(()=>{this.onEnterCompleted(),r()})})}leave(t,e,r){return new Promise(i=>{this.onLeave(),t.leave({trigger:e,from:this.content}).then(()=>{r&&this.remove(),this.onLeaveCompleted(),i()})})}}class c{constructor(){this.data=new Map,this.regexCache=new Map}add(t,e,r){this.data.has(t)||(this.data.set(t,new Map),this.regexCache.set(t,new RegExp(`^${t}$`))),this.data.get(t).set(e,r),this.regexCache.set(e,new RegExp(`^${e}$`))}findMatch(t,e){for(const[r,i]of this.data)if(t.pathname.match(this.regexCache.get(r))){for(const[t,r]of i)if(e.pathname.match(this.regexCache.get(t)))return r;break}return null}}const l="A transition is currently in progress";class d{constructor(t={}){this.isTransitioning=!1,this.currentCacheEntry=null,this.cache=new Map,this.activePromises=new Map,this.onClick=t=>{if(!t.metaKey&&!t.ctrlKey){const e=r(t.currentTarget.href);if(this.currentLocation=r(window.location.href),this.currentLocation.host!==e.host)return;if(this.currentLocation.href!==e.href||this.currentLocation.hasHash&&!e.hasHash)return t.preventDefault(),void this.navigateTo(e.raw,t.currentTarget.dataset.transition||!1,t.currentTarget).catch(t=>console.warn(t));this.currentLocation.hasHash||e.hasHash||t.preventDefault()}},this.onPopstate=()=>!(window.location.pathname===this.currentLocation.pathname&&!this.isPopping)&&(this.allowInterruption||!this.isTransitioning&&!this.isPopping?(this.isPopping||(this.popTarget=window.location.href),this.isPopping=!0,void this.navigateTo(window.location.href,!1,"popstate")):(window.history.pushState({},"",this.popTarget),console.warn(l),!1)),this.onPrefetch=t=>{const e=r(t.currentTarget.href);this.currentLocation.host===e.host&&this.preload(t.currentTarget.href,!1)};const{links:e="a:not([target]):not([href^=\\#]):not([data-taxi-ignore])",removeOldContent:i=!0,allowInterruption:n=!1,bypassCache:s=!1,enablePrefetch:a=!0,renderers:c={default:h},transitions:d={default:o},reloadJsFilter:u=(t=>void 0!==t.dataset.taxiReload),reloadCssFilter:f=(t=>!0)}=t;this.renderers=c,this.transitions=d,this.defaultRenderer=this.renderers.default||h,this.defaultTransition=this.transitions.default||o,this.wrapper=document.querySelector("[data-taxi]"),this.reloadJsFilter=u,this.reloadCssFilter=f,this.removeOldContent=i,this.allowInterruption=n,this.bypassCache=s,this.enablePrefetch=a,this.cache=new Map,this.isPopping=!1,this.attachEvents(e),this.currentLocation=r(window.location.href),this.cache.set(this.currentLocation.href,this.createCacheEntry(document.cloneNode(!0),window.location.href)),this.currentCacheEntry=this.cache.get(this.currentLocation.href),this.currentCacheEntry.renderer.initialLoad()}setDefaultRenderer(t){this.defaultRenderer=this.renderers[t]}setDefaultTransition(t){this.defaultTransition=this.transitions[t]}addRoute(t,e,r){this.router||(this.router=new c),this.router.add(t,e,r)}preload(t,e=!1){var i=this;return t=r(t).href,this.cache.has(t)?Promise.resolve():this.fetch(t,!1).then(async function(r){i.cache.set(t,i.createCacheEntry(r.html,r.url)),e&&i.cache.get(t).renderer.createDom()}).catch(t=>console.warn(t))}updateCache(t){const e=r(t||window.location.href).href;this.cache.has(e)&&this.cache.delete(e),this.cache.set(e,this.createCacheEntry(document.cloneNode(!0),e))}clearCache(t){const e=r(t||window.location.href).href;this.cache.has(e)&&this.cache.delete(e)}navigateTo(t,e=!1,i=!1){var n=this;return new Promise((s,a)=>{if(!this.allowInterruption&&this.isTransitioning)return void a(new Error(l));this.isTransitioning=!0,this.isPopping=!0,this.targetLocation=r(t),this.popTarget=window.location.href;const o=new(this.chooseTransition(e))({wrapper:this.wrapper});let h;if(this.bypassCache||!this.cache.has(this.targetLocation.href)||this.cache.get(this.targetLocation.href).skipCache){const e=this.fetch(this.targetLocation.href).then(t=>{this.cache.set(this.targetLocation.href,this.createCacheEntry(t.html,t.url)),this.cache.get(this.targetLocation.href).renderer.createDom()}).catch(e=>{window.location.href=t});h=this.beforeFetch(this.targetLocation,o,i).then(async function(){return e.then(async function(){return await n.afterFetch(n.targetLocation,o,n.cache.get(n.targetLocation.href),i)})})}else this.cache.get(this.targetLocation.href).renderer.createDom(),h=this.beforeFetch(this.targetLocation,o,i).then(async function(){return await n.afterFetch(n.targetLocation,o,n.cache.get(n.targetLocation.href),i)});h.then(()=>{s()})})}on(e,r){t.on(e,r)}off(e,r){t.off(e,r)}beforeFetch(e,r,i){return t.emit("NAVIGATE_OUT",{from:this.currentCacheEntry,trigger:i}),new Promise(t=>{this.currentCacheEntry.renderer.leave(r,i,this.removeOldContent).then(()=>{"popstate"!==i&&window.history.pushState({},"",e.raw),t()})})}afterFetch(e,r,i,n){return this.currentLocation=e,this.popTarget=this.currentLocation.href,new Promise(s=>{i.renderer.update(),t.emit("NAVIGATE_IN",{from:this.currentCacheEntry,to:i,trigger:n}),this.reloadJsFilter&&this.loadScripts(i.scripts),this.reloadCssFilter&&this.loadStyles(i.styles),"popstate"!==n&&e.href!==i.finalUrl&&window.history.replaceState({},"",i.finalUrl),i.renderer.enter(r,n).then(()=>{t.emit("NAVIGATE_END",{from:this.currentCacheEntry,to:i,trigger:n}),this.currentCacheEntry=i,this.isTransitioning=!1,this.isPopping=!1,s()})})}loadScripts(t){const e=[...t],r=Array.from(document.querySelectorAll("script")).filter(this.reloadJsFilter);for(let t=0;t!t.href||(e.find(e=>e.href===t.href)?void 0:(document.body.append(t),!1)));for(let t=0;t{let s;fetch(t,{mode:"same-origin",method:"GET",headers:{"X-Requested-With":"Taxi"},credentials:"same-origin"}).then(e=>(e.ok||(n("Taxi encountered a non 2xx HTTP status code"),r&&(window.location.href=t)),s=e.url,e.text())).then(t=>{var r;i({html:(r=t,"string"==typeof r?e.parseFromString(r,"text/html"):r),url:s})}).catch(e=>{n(e),r&&(window.location.href=t)}).finally(()=>{this.activePromises.delete(t)})});return this.activePromises.set(t,i),i}chooseTransition(t){var e;if(t)return this.transitions[t];const r=null==(e=this.router)?void 0:e.findMatch(this.currentLocation,this.targetLocation);return r?this.transitions[r]:this.defaultTransition}createCacheEntry(t,e){const r=t.querySelector("[data-taxi-view]"),i=r.dataset.taxiView.length?this.renderers[r.dataset.taxiView]:this.defaultRenderer;return i||console.warn(`The Renderer "${r.dataset.taxiView}" was set in the data-taxi-view of the requested page, but not registered in Taxi.`),{page:t,content:r,finalUrl:e,skipCache:r.hasAttribute("data-taxi-nocache"),scripts:this.reloadJsFilter?Array.from(t.querySelectorAll("script")).filter(this.reloadJsFilter):[],styles:this.reloadCssFilter?Array.from(t.querySelectorAll('link[rel="stylesheet"], style')).filter(this.reloadCssFilter):[],title:t.title,renderer:new i({wrapper:this.wrapper,title:t.title,content:r,page:t})}}}export{d as Core,h as Renderer,o as Transition}; +import t from"@unseenco/e";const e=new DOMParser;function r(t){const e=new URL(t,window.location.origin),r=e.hash.length?t.replace(e.hash,""):null;return{hasHash:e.hash.length>0,pathname:e.pathname,host:e.host,search:e.search,raw:t,href:r||e.href}}function i(t,e){t.parentNode.replaceChild(s(t,e),t)}function n(t,e){("HEAD"===t.parentNode.tagName?document.head:document.body).appendChild(s(t,e))}function s(t,e){const r=document.createElement(e);for(let e=0;e{this.onLeave(a({},t,{done:e}))})}enter(t){return new Promise(e=>{this.onEnter(a({},t,{done:e}))})}onLeave({done:t}){t()}onEnter({done:t}){t()}}class h{constructor({content:t,page:e,title:r,wrapper:i}){this._contentString=t.outerHTML,this._DOM=null,this.page=e,this.title=r,this.wrapper=i,this.content=this.wrapper.lastElementChild}onEnter(){}onEnterCompleted(){}onLeave(){}onLeaveCompleted(){}initialLoad(){this.onEnter(),this.onEnterCompleted()}update(){document.title=this.title,this.wrapper.appendChild(this._DOM.firstElementChild),this.content=this.wrapper.lastElementChild,this._DOM=null}createDom(){this._DOM||(this._DOM=document.createElement("div"),this._DOM.innerHTML=this._contentString)}remove(){this.wrapper.firstElementChild.remove()}enter(t,e){return new Promise(r=>{this.onEnter(),t.enter({trigger:e,to:this.content}).then(()=>{this.onEnterCompleted(),r()})})}leave(t,e,r){return new Promise(i=>{this.onLeave(),t.leave({trigger:e,from:this.content}).then(()=>{r&&this.remove(),this.onLeaveCompleted(),i()})})}}class c{constructor(){this.data=new Map,this.regexCache=new Map}add(t,e,r){this.data.has(t)||(this.data.set(t,new Map),this.regexCache.set(t,new RegExp(`^${t}$`))),this.data.get(t).set(e,r),this.regexCache.set(e,new RegExp(`^${e}$`))}findMatch(t,e){for(const[r,i]of this.data)if(t.pathname.match(this.regexCache.get(r))){for(const[t,r]of i)if(e.pathname.match(this.regexCache.get(t)))return r;break}return null}}const l="A transition is currently in progress";class d{constructor(t={}){this.isTransitioning=!1,this.currentCacheEntry=null,this.cache=new Map,this.activePromises=new Map,this.onClick=t=>{if(!t.metaKey&&!t.ctrlKey){const e=r(t.currentTarget.href);if(this.currentLocation=r(window.location.href),this.currentLocation.host!==e.host)return;if(this.currentLocation.href!==e.href||this.currentLocation.hasHash&&!e.hasHash)return t.preventDefault(),void this.navigateTo(e.raw,t.currentTarget.dataset.transition||!1,t.currentTarget).catch(t=>console.warn(t));this.currentLocation.hasHash||e.hasHash||t.preventDefault()}},this.onPopstate=()=>!(window.location.pathname===this.currentLocation.pathname&&window.location.search===this.currentLocation.search&&!this.isPopping)&&(this.allowInterruption||!this.isTransitioning&&!this.isPopping?(this.isPopping||(this.popTarget=window.location.href),this.isPopping=!0,void this.navigateTo(window.location.href,!1,"popstate")):(window.history.pushState({},"",this.popTarget),console.warn(l),!1)),this.onPrefetch=t=>{const e=r(t.currentTarget.href);this.currentLocation.host===e.host&&this.preload(t.currentTarget.href,!1)};const{links:e="a:not([target]):not([href^=\\#]):not([data-taxi-ignore])",removeOldContent:i=!0,allowInterruption:n=!1,bypassCache:s=!1,enablePrefetch:a=!0,renderers:c={default:h},transitions:d={default:o},reloadJsFilter:u=(t=>void 0!==t.dataset.taxiReload),reloadCssFilter:f=(t=>!0)}=t;this.renderers=c,this.transitions=d,this.defaultRenderer=this.renderers.default||h,this.defaultTransition=this.transitions.default||o,this.wrapper=document.querySelector("[data-taxi]"),this.reloadJsFilter=u,this.reloadCssFilter=f,this.removeOldContent=i,this.allowInterruption=n,this.bypassCache=s,this.enablePrefetch=a,this.cache=new Map,this.isPopping=!1,this.attachEvents(e),this.currentLocation=r(window.location.href),this.cache.set(this.currentLocation.href,this.createCacheEntry(document.cloneNode(!0),window.location.href)),this.currentCacheEntry=this.cache.get(this.currentLocation.href),this.currentCacheEntry.renderer.initialLoad()}setDefaultRenderer(t){this.defaultRenderer=this.renderers[t]}setDefaultTransition(t){this.defaultTransition=this.transitions[t]}addRoute(t,e,r){this.router||(this.router=new c),this.router.add(t,e,r)}preload(t,e=!1){var i=this;return t=r(t).href,this.cache.has(t)?Promise.resolve():this.fetch(t,!1).then(async function(r){i.cache.set(t,i.createCacheEntry(r.html,r.url)),e&&i.cache.get(t).renderer.createDom()}).catch(t=>console.warn(t))}updateCache(t){const e=r(t||window.location.href).href;this.cache.has(e)&&this.cache.delete(e),this.cache.set(e,this.createCacheEntry(document.cloneNode(!0),e))}clearCache(t){const e=r(t||window.location.href).href;this.cache.has(e)&&this.cache.delete(e)}navigateTo(t,e=!1,i=!1){var n=this;return new Promise((s,a)=>{if(!this.allowInterruption&&this.isTransitioning)return void a(new Error(l));this.isTransitioning=!0,this.isPopping=!0,this.targetLocation=r(t),this.popTarget=window.location.href;const o=new(this.chooseTransition(e))({wrapper:this.wrapper});let h;if(this.bypassCache||!this.cache.has(this.targetLocation.href)||this.cache.get(this.targetLocation.href).skipCache){const e=this.fetch(this.targetLocation.href).then(t=>{this.cache.set(this.targetLocation.href,this.createCacheEntry(t.html,t.url)),this.cache.get(this.targetLocation.href).renderer.createDom()}).catch(e=>{window.location.href=t});h=this.beforeFetch(this.targetLocation,o,i).then(async function(){return e.then(async function(){return await n.afterFetch(n.targetLocation,o,n.cache.get(n.targetLocation.href),i)})})}else this.cache.get(this.targetLocation.href).renderer.createDom(),h=this.beforeFetch(this.targetLocation,o,i).then(async function(){return await n.afterFetch(n.targetLocation,o,n.cache.get(n.targetLocation.href),i)});h.then(()=>{s()})})}on(e,r){t.on(e,r)}off(e,r){t.off(e,r)}beforeFetch(e,r,i){return t.emit("NAVIGATE_OUT",{from:this.currentCacheEntry,trigger:i}),new Promise(t=>{this.currentCacheEntry.renderer.leave(r,i,this.removeOldContent).then(()=>{"popstate"!==i&&window.history.pushState({},"",e.raw),t()})})}afterFetch(e,r,i,n){return this.currentLocation=e,this.popTarget=this.currentLocation.href,new Promise(s=>{i.renderer.update(),t.emit("NAVIGATE_IN",{from:this.currentCacheEntry,to:i,trigger:n}),this.reloadJsFilter&&this.loadScripts(i.scripts),this.reloadCssFilter&&this.loadStyles(i.styles),"popstate"!==n&&e.href!==i.finalUrl&&window.history.replaceState({},"",i.finalUrl),i.renderer.enter(r,n).then(()=>{t.emit("NAVIGATE_END",{from:this.currentCacheEntry,to:i,trigger:n}),this.currentCacheEntry=i,this.isTransitioning=!1,this.isPopping=!1,s()})})}loadScripts(t){const e=[...t],r=Array.from(document.querySelectorAll("script")).filter(this.reloadJsFilter);for(let t=0;t!t.href||(e.find(e=>e.href===t.href)?void 0:(document.body.append(t),!1)));for(let t=0;t{let s;fetch(t,{mode:"same-origin",method:"GET",headers:{"X-Requested-With":"Taxi"},credentials:"same-origin"}).then(e=>(e.ok||(n("Taxi encountered a non 2xx HTTP status code"),r&&(window.location.href=t)),s=e.url,e.text())).then(t=>{var r;i({html:(r=t,"string"==typeof r?e.parseFromString(r,"text/html"):r),url:s})}).catch(e=>{n(e),r&&(window.location.href=t)}).finally(()=>{this.activePromises.delete(t)})});return this.activePromises.set(t,i),i}chooseTransition(t){var e;if(t)return this.transitions[t];const r=null==(e=this.router)?void 0:e.findMatch(this.currentLocation,this.targetLocation);return r?this.transitions[r]:this.defaultTransition}createCacheEntry(t,e){const r=t.querySelector("[data-taxi-view]"),i=r.dataset.taxiView.length?this.renderers[r.dataset.taxiView]:this.defaultRenderer;return i||console.warn(`The Renderer "${r.dataset.taxiView}" was set in the data-taxi-view of the requested page, but not registered in Taxi.`),{page:t,content:r,finalUrl:e,skipCache:r.hasAttribute("data-taxi-nocache"),scripts:this.reloadJsFilter?Array.from(t.querySelectorAll("script")).filter(this.reloadJsFilter):[],styles:this.reloadCssFilter?Array.from(t.querySelectorAll('link[rel="stylesheet"], style')).filter(this.reloadCssFilter):[],title:t.title,renderer:new i({wrapper:this.wrapper,title:t.title,content:r,page:t})}}}export{d as Core,h as Renderer,o as Transition}; //# sourceMappingURL=taxi.modern.js.map diff --git a/dist/taxi.modern.js.map b/dist/taxi.modern.js.map index 1984844..c0d7662 100644 --- a/dist/taxi.modern.js.map +++ b/dist/taxi.modern.js.map @@ -1 +1 @@ -{"version":3,"file":"taxi.modern.js","sources":["../src/helpers.js","../src/Transition.js","../src/Renderer.js","../src/RouteStore.js","../src/Core.js"],"sourcesContent":["const parser = new DOMParser()\n\n/**\n * Parse a HTML string into a proper Document.\n *\n * @param {string|Document} html\n * @return {Document|*}\n */\nexport function parseDom(html) {\n\treturn typeof html === 'string' ? parser.parseFromString(html, 'text/html') : html\n}\n\n/**\n * Extract details from a given URL string. Assumed to be on the current TLD.\n *\n * @param {string} url\n * @return {{raw: string, href: string, host: string, hasHash: boolean, pathname: string}}\n */\nexport function processUrl(url) {\n\tconst details = new URL(url, window.location.origin)\n\tconst normalized = details.hash.length ? url.replace(details.hash, '') : null\n\n\treturn {\n\t\thasHash: details.hash.length > 0,\n\t\tpathname: details.pathname,\n\t\thost: details.host,\n\t\traw: url,\n\t\thref: normalized || details.href\n\t}\n}\n\n/**\n * Reloads a provided script/stylesheet by replacing with itself.\n *\n * @param {HTMLElement|HTMLScriptElement|HTMLStyleElement} node\n * @param {string} elementType - 'SCRIPT' or 'STYLE'\n */\nexport function reloadElement(node, elementType) {\n\tnode.parentNode.replaceChild(duplicateElement(node, elementType), node)\n}\n\n/**\n * Loads a provided script/stylesheet by appending a clone to the current document.\n *\n * @param {HTMLElement|HTMLStyleElement} node\n * @param {string} elementType - 'SCRIPT' or 'STYLE'\n */\nexport function appendElement(node, elementType) {\n\tconst target = node.parentNode.tagName === 'HEAD' ? document.head : document.body\n\ttarget.appendChild(duplicateElement(node, elementType))\n}\n\n/**\n * Creates a clone of a given HTMLElement or HTMLStyleElement\n *\n * @param {HTMLElement|HTMLStyleElement} node\n * @param {string} elementType - 'SCRIPT' or 'STYLE'\n * @return {HTMLElement|HTMLStyleElement}\n */\nexport function duplicateElement(node, elementType) {\n\tconst replacement = document.createElement(elementType)\n\n\tfor (let k = 0; k < node.attributes.length; k++) {\n\t\tconst attr = node.attributes[k]\n\t\treplacement.setAttribute(attr.nodeName, attr.nodeValue)\n\t}\n\n\t// Inline Script or Style\n\tif (node.innerHTML) {\n\t\treplacement.innerHTML = node.innerHTML\n\t}\n\n\treturn replacement\n}\n","export default class Transition {\n\t/**\n\t * @param {{wrapper: HTMLElement}} props\n\t */\n\tconstructor({ wrapper }) {\n\t\tthis.wrapper = wrapper\n\t}\n\n\t/**\n\t * @param {{ from: HTMLElement|Element, trigger: string|HTMLElement|false }} props\n\t * @return {Promise}\n\t */\n\tleave(props) {\n\t\treturn new Promise((resolve) => {\n\t\t\tthis.onLeave({ ...props, done: resolve })\n\t\t})\n\t}\n\n\t/**\n\t * @param {{ to: HTMLElement|Element, trigger: string|HTMLElement|false }} props\n\t * @return {Promise}\n\t */\n\tenter(props) {\n\t\treturn new Promise((resolve) => {\n\t\t\tthis.onEnter({ ...props, done: resolve })\n\t\t})\n\t}\n\n\t/**\n\t * Handle the transition leaving the previous page.\n\t * @param {{from: HTMLElement|Element, trigger: string|HTMLElement|false, done: function}} props\n\t */\n\tonLeave({ from, trigger, done }) {\n\t\tdone()\n\t}\n\n\t/**\n\t * Handle the transition entering the next page.\n\t * @param {{to: HTMLElement|Element, trigger: string|HTMLElement|false, done: function}} props\n\t */\n\tonEnter({ to, trigger, done }) {\n\t\tdone()\n\t}\n}\n","import Transition from \"./Transition\"\n\nexport default class Renderer {\n\t/**\n\t * @param {{content: HTMLElement|Element, page: Document|Node, title: string, wrapper: Element}} props\n\t */\n\tconstructor({ content, page, title, wrapper }) {\n\t\tthis._contentString = content.outerHTML\n\t\tthis._DOM = null\n\t\tthis.page = page\n\t\tthis.title = title\n\t\tthis.wrapper = wrapper\n\t\tthis.content = this.wrapper.lastElementChild\n\t}\n\n\tonEnter() {\n\n\t}\n\n\tonEnterCompleted() {\n\n\t}\n\n\tonLeave() {\n\n\t}\n\n\tonLeaveCompleted() {\n\n\t}\n\n\tinitialLoad() {\n\t\tthis.onEnter()\n\t\tthis.onEnterCompleted()\n\t}\n\n\tupdate() {\n\t\tdocument.title = this.title\n\t\tthis.wrapper.appendChild(this._DOM.firstElementChild)\n\t\tthis.content = this.wrapper.lastElementChild\n\t\tthis._DOM = null\n\t}\n\n\tcreateDom() {\n\t\tif (!this._DOM) {\n\t\t\tthis._DOM = document.createElement('div')\n\t\t\tthis._DOM.innerHTML = this._contentString\n\t\t}\n\t}\n\n\tremove() {\n\t\tthis.wrapper.firstElementChild.remove()\n\t}\n\n\t/**\n\t * Called when transitioning into the current page.\n\t * @param {Transition} transition\n\t * @param {string|HTMLElement|false} trigger\n\t * @return {Promise}\n\t */\n\tenter(transition, trigger) {\n\t\treturn new Promise((resolve) => {\n\t\t\tthis.onEnter()\n\n\t\t\ttransition.enter({ trigger, to: this.content })\n\t\t\t\t.then(() => {\n\t\t\t\t\tthis.onEnterCompleted()\n\t\t\t\t\tresolve()\n\t\t\t\t})\n\t\t})\n\t}\n\n\t/**\n\t * Called when transitioning away from the current page.\n\t * @param {Transition} transition\n\t * @param {string|HTMLElement|false} trigger\n\t * @param {boolean} removeOldContent\n\t * @return {Promise}\n\t */\n\tleave(transition, trigger, removeOldContent) {\n\t\treturn new Promise((resolve) => {\n\t\t\tthis.onLeave()\n\n\t\t\ttransition.leave({ trigger, from: this.content })\n\t\t\t\t.then(() => {\n\t\t\t\t\tif (removeOldContent) {\n\t\t\t\t\t\tthis.remove()\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.onLeaveCompleted()\n\t\t\t\t\tresolve()\n\t\t\t\t})\n\t\t})\n\t}\n}\n","export default class RouteStore {\n\t/**\n\t * @type {Map>}\n\t */\n\tdata = new Map()\n\n\t/**\n\t * @type {Map}\n\t */\n\tregexCache = new Map()\n\n\t/**\n\t *\n\t * @param {string} fromPattern\n\t * @param {string} toPattern\n\t * @param {string} transition\n\t */\n\tadd(fromPattern, toPattern, transition) {\n\t\tif (!this.data.has(fromPattern)) {\n\t\t\tthis.data.set(fromPattern, new Map())\n\t\t\tthis.regexCache.set(fromPattern, new RegExp(`^${fromPattern}$`))\n\t\t}\n\n\t\tthis.data.get(fromPattern).set(toPattern, transition)\n\t\tthis.regexCache.set(toPattern, new RegExp(`^${toPattern}$`))\n\t}\n\n\t/**\n\t *\n\t * @param {{ raw: string, href: string, hasHash: boolean, pathname: string }} currentUrl\n\t * @param {{ raw: string, href: string, hasHash: boolean, pathname: string }} nextUrl\n\t * @return {string|null}\n\t */\n\tfindMatch(currentUrl, nextUrl) {\n\t\t// Loop through all from patterns\n\t\tfor (const [fromPattern, potentialMatches] of this.data) {\n\t\t\t// If we have a match\n\t\t\tif (currentUrl.pathname.match(this.regexCache.get(fromPattern))) {\n\t\t\t\t// loop through all associated to patterns\n\t\t\t\tfor (const [toPattern, transition] of potentialMatches) {\n\t\t\t\t\t// If we find a match, return it\n\t\t\t\t\tif (nextUrl.pathname.match(this.regexCache.get(toPattern))) {\n\t\t\t\t\t\treturn transition\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\treturn null\n\t}\n}\n","import E from '@unseenco/e'\nimport { appendElement, parseDom, processUrl, reloadElement } from './helpers'\nimport Transition from './Transition'\nimport Renderer from './Renderer'\nimport RouteStore from './RouteStore'\n\nconst IN_PROGRESS = 'A transition is currently in progress'\n\n/**\n * @typedef CacheEntry\n * @type {object}\n * @property {typeof Renderer|Renderer} renderer\n * @property {Document|Node} page\n * @property {array} scripts\n * @property {HTMLLinkElement[]} styles\n * @property {string} finalUrl\n * @property {boolean} skipCache\n * @property {string} title\n * @property {HTMLElement|Element} content\n */\n\nexport default class Core {\n\tisTransitioning = false\n\n\t/**\n\t * @type {CacheEntry|null}\n\t */\n\tcurrentCacheEntry = null\n\n\t/**\n\t * @type {Map}\n\t */\n\tcache = new Map()\n\n\t/**\n\t * @private\n\t * @type {Map}\n\t */\n\tactivePromises = new Map()\n\n\t/**\n\t * @param {{\n\t * \t\tlinks?: string,\n\t * \t\tremoveOldContent?: boolean,\n\t * \t\tallowInterruption?: boolean,\n\t * \t\tbypassCache?: boolean,\n\t * \t\tenablePrefetch?: boolean,\n\t * \t\trenderers?: Object.,\n\t * \t\ttransitions?: Object.,\n\t * \t\treloadJsFilter?: boolean|function(HTMLElement): boolean,\n\t * \t\treloadCssFilter?: boolean|function(HTMLLinkElement): boolean\n\t * }} parameters\n\t */\n\tconstructor(parameters = {}) {\n\t\tconst {\n\t\t\tlinks = 'a:not([target]):not([href^=\\\\#]):not([data-taxi-ignore])',\n\t\t\tremoveOldContent = true,\n\t\t\tallowInterruption = false,\n\t\t\tbypassCache = false,\n\t\t\tenablePrefetch = true,\n\t\t\trenderers = {\n\t\t\t\tdefault: Renderer\n\t\t\t},\n\t\t\ttransitions = {\n\t\t\t\tdefault: Transition\n\t\t\t},\n\t\t\treloadJsFilter = (element) => element.dataset.taxiReload !== undefined,\n\t\t\treloadCssFilter = (element) => true //element.dataset.taxiReload !== undefined\n\t\t} = parameters\n\n\t\tthis.renderers = renderers\n\t\tthis.transitions = transitions\n\t\tthis.defaultRenderer = this.renderers.default || Renderer\n\t\tthis.defaultTransition = this.transitions.default || Transition\n\t\tthis.wrapper = document.querySelector('[data-taxi]')\n\t\tthis.reloadJsFilter = reloadJsFilter\n\t\tthis.reloadCssFilter = reloadCssFilter\n\t\tthis.removeOldContent = removeOldContent\n\t\tthis.allowInterruption = allowInterruption\n\t\tthis.bypassCache = bypassCache\n\t\tthis.enablePrefetch = enablePrefetch\n\t\tthis.cache = new Map()\n\t\tthis.isPopping = false\n\n\t\t// Add delegated link events\n\t\tthis.attachEvents(links)\n\n\t\tthis.currentLocation = processUrl(window.location.href)\n\n\t\t// as this is the initial page load, prime this page into the cache\n\t\tthis.cache.set(this.currentLocation.href, this.createCacheEntry(document.cloneNode(true), window.location.href))\n\n\t\t// fire the current Renderer enter methods\n\t\tthis.currentCacheEntry = this.cache.get(this.currentLocation.href)\n\t\tthis.currentCacheEntry.renderer.initialLoad()\n\t}\n\n\t/**\n\t * @param {string} renderer\n\t */\n\tsetDefaultRenderer(renderer) {\n\t\tthis.defaultRenderer = this.renderers[renderer]\n\t}\n\n\t/**\n\t * @param {string} transition\n\t */\n\tsetDefaultTransition(transition) {\n\t\tthis.defaultTransition = this.transitions[transition]\n\t}\n\n\t/**\n\t * Registers a route into the RouteStore\n\t *\n\t * @param {string} fromPattern\n\t * @param {string} toPattern\n\t * @param {string} transition\n\t */\n\taddRoute(fromPattern, toPattern, transition) {\n\t\tif (!this.router) {\n\t\t\tthis.router = new RouteStore()\n\t\t}\n\n\t\tthis.router.add(fromPattern, toPattern, transition)\n\t}\n\n\t/**\n\t * Prime the cache for a given URL\n\t *\n\t * @param {string} url\n\t * @param {boolean} [preloadAssets]\n\t * @return {Promise}\n\t */\n\tpreload(url, preloadAssets = false) {\n\t\t// convert relative URLs to absolute\n\t\turl = processUrl(url).href\n\n\t\tif (!this.cache.has(url)) {\n\t\t\treturn this.fetch(url, false)\n\t\t\t\t.then(async (response) => {\n\t\t\t\t\tthis.cache.set(url, this.createCacheEntry(response.html, response.url))\n\n\t\t\t\t\tif (preloadAssets) {\n\t\t\t\t\t\tthis.cache.get(url).renderer.createDom()\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\t.catch(err => console.warn(err))\n\t\t}\n\n\t\treturn Promise.resolve()\n\t}\n\n\t/**\n\t * Updates the HTML cache for a given URL.\n\t * If no URL is passed, then cache for the current page is updated.\n\t * Useful when adding/removing content via AJAX such as a search page or infinite loader.\n\t *\n\t * @param {string} [url]\n\t */\n\tupdateCache(url) {\n\t\tconst key = processUrl(url || window.location.href).href\n\n\t\tif (this.cache.has(key)) {\n\t\t\tthis.cache.delete(key)\n\t\t}\n\n\t\tthis.cache.set(key, this.createCacheEntry(document.cloneNode(true), key))\n\t}\n\n\t/**\n\t * Clears the cache for a given URL.\n\t * If no URL is passed, then cache for the current page is cleared.\n\t *\n\t * @param {string} [url]\n\t */\n\tclearCache(url) {\n\t\tconst key = processUrl(url || window.location.href).href\n\n\t\tif (this.cache.has(key)) {\n\t\t\tthis.cache.delete(key)\n\t\t}\n\t}\n\n\t/**\n\t * @param {string} url\n\t * @param {string|false} [transition]\n\t * @param {string|false|HTMLElement} [trigger]\n\t * @return {Promise}\n\t */\n\tnavigateTo(url, transition = false, trigger = false) {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\t// Don't allow multiple navigations to occur at once\n\t\t\tif (!this.allowInterruption && this.isTransitioning) {\n\t\t\t\treject(new Error(IN_PROGRESS))\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tthis.isTransitioning = true\n\t\t\tthis.isPopping = true\n\t\t\tthis.targetLocation = processUrl(url)\n\t\t\tthis.popTarget = window.location.href\n\n\t\t\tconst TransitionClass = new (this.chooseTransition(transition))({ wrapper: this.wrapper })\n\n\t\t\tlet navigationPromise\n\n\t\t\tif (this.bypassCache || !this.cache.has(this.targetLocation.href) || this.cache.get(this.targetLocation.href).skipCache) {\n\t\t\t\tconst fetched = this.fetch(this.targetLocation.href)\n\t\t\t\t\t.then((response) => {\n\t\t\t\t\t\tthis.cache.set(this.targetLocation.href, this.createCacheEntry(response.html, response.url))\n\t\t\t\t\t\tthis.cache.get(this.targetLocation.href).renderer.createDom()\n\t\t\t\t\t})\n\t\t\t\t\t.catch(err => {\n\t\t\t\t\t\t// we encountered a 4** or 5** error, redirect to the requested URL\n\t\t\t\t\t\twindow.location.href = url\n\t\t\t\t\t})\n\n\t\t\t\tnavigationPromise = this.beforeFetch(this.targetLocation, TransitionClass, trigger)\n\t\t\t\t\t.then(async () => {\n\t\t\t\t\t\treturn fetched.then(async () => {\n\t\t\t\t\t\t\treturn await this.afterFetch(this.targetLocation, TransitionClass, this.cache.get(this.targetLocation.href), trigger)\n\t\t\t\t\t\t})\n\t\t\t\t\t})\n\t\t\t} else {\n\t\t\t\tthis.cache.get(this.targetLocation.href).renderer.createDom()\n\n\t\t\t\tnavigationPromise = this.beforeFetch(this.targetLocation, TransitionClass, trigger)\n\t\t\t\t\t.then(async () => {\n\t\t\t\t\t\treturn await this.afterFetch(this.targetLocation, TransitionClass, this.cache.get(this.targetLocation.href), trigger)\n\t\t\t\t\t})\n\t\t\t}\n\n\t\t\tnavigationPromise.then(() => {\n\t\t\t\tresolve()\n\t\t\t})\n\t\t})\n\t}\n\n\t/**\n\t * Add an event listener.\n\t * @param {string} event\n\t * @param {any} callback\n\t */\n\ton(event, callback) {\n\t\tE.on(event, callback)\n\t}\n\n\t/**\n\t * Remove an event listener.\n\t * @param {string} event\n\t * @param {any} [callback]\n\t */\n\toff(event, callback) {\n\t\tE.off(event, callback)\n\t}\n\n\t/**\n\t * @private\n\t * @param {{ raw: string, href: string, hasHash: boolean, pathname: string }} url\n\t * @param {Transition} TransitionClass\n\t * @param {string|HTMLElement|false} trigger\n\t * @return {Promise}\n\t */\n\tbeforeFetch(url, TransitionClass, trigger) {\n\t\tE.emit('NAVIGATE_OUT', {\n\t\t\tfrom: this.currentCacheEntry,\n\t\t\ttrigger\n\t\t})\n\n\t\treturn new Promise((resolve) => {\n\t\t\tthis.currentCacheEntry.renderer.leave(TransitionClass, trigger, this.removeOldContent)\n\t\t\t\t.then(() => {\n\t\t\t\t\tif (trigger !== 'popstate') {\n\t\t\t\t\t\twindow.history.pushState({}, '', url.raw)\n\t\t\t\t\t}\n\n\t\t\t\t\tresolve()\n\t\t\t\t})\n\t\t})\n\t}\n\n\t/**\n\t * @private\n\t * @param {{ raw: string, href: string, host: string, hasHash: boolean, pathname: string }} url\n\t * @param {Transition} TransitionClass\n\t * @param {CacheEntry} entry\n\t * @param {string|HTMLElement|false} trigger\n\t * @return {Promise}\n\t */\n\tafterFetch(url, TransitionClass, entry, trigger) {\n\t\tthis.currentLocation = url\n\t\tthis.popTarget = this.currentLocation.href\n\n\t\treturn new Promise((resolve) => {\n\t\t\tentry.renderer.update()\n\n\t\t\tE.emit('NAVIGATE_IN', {\n\t\t\t\tfrom: this.currentCacheEntry,\n\t\t\t\tto: entry,\n\t\t\t\ttrigger\n\t\t\t})\n\n\t\t\tif (this.reloadJsFilter) {\n\t\t\t\tthis.loadScripts(entry.scripts)\n\t\t\t}\n\n\t\t\tif (this.reloadCssFilter) {\n\t\t\t\tthis.loadStyles(entry.styles)\n\t\t\t}\n\n\t\t\t// If the fetched url had a redirect chain, then replace the history to reflect the final resolved URL\n\t\t\tif (trigger !== 'popstate' && url.href !== entry.finalUrl) {\n\t\t\t\twindow.history.replaceState({}, '', entry.finalUrl)\n\t\t\t}\n\n\t\t\tentry.renderer.enter(TransitionClass, trigger)\n\t\t\t\t.then(() => {\n\t\t\t\t\tE.emit('NAVIGATE_END', {\n\t\t\t\t\t\tfrom: this.currentCacheEntry,\n\t\t\t\t\t\tto: entry,\n\t\t\t\t\t\ttrigger\n\t\t\t\t\t})\n\n\t\t\t\t\tthis.currentCacheEntry = entry\n\t\t\t\t\tthis.isTransitioning = false\n\t\t\t\t\tthis.isPopping = false\n\t\t\t\t\tresolve()\n\t\t\t\t})\n\t\t})\n\t}\n\n\t/**\n\t * Load up scripts from the target page if needed\n\t *\n\t * @param {HTMLElement[]} cachedScripts\n\t */\n\tloadScripts(cachedScripts) {\n\t\tconst newScripts = [...cachedScripts]\n\t\tconst currentScripts = Array.from(document.querySelectorAll('script')).filter(this.reloadJsFilter)\n\n\t\t// loop through all new scripts\n\t\tfor (let i = 0; i < currentScripts.length; i++) {\n\t\t\tfor (let n = 0; n < newScripts.length; n++) {\n\t\t\t\tif (currentScripts[i].outerHTML === newScripts[n].outerHTML) {\n\t\t\t\t\treloadElement(currentScripts[i], 'SCRIPT')\n\t\t\t\t\tnewScripts.splice(n, 1)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tfor (const script of newScripts) {\n\t\t\tappendElement(script, 'SCRIPT')\n\t\t}\n\t}\n\n\t/**\n\t * Load up styles from the target page if needed\n\t *\n\t * @param {Array} cachedStyles\n\t */\n\tloadStyles(cachedStyles) {\n\t\tconst currentStyles = Array.from(document.querySelectorAll('link[rel=\"stylesheet\"]')).filter(this.reloadCssFilter)\n\t\tconst currentInlineStyles = Array.from(document.querySelectorAll('style')).filter(this.reloadCssFilter)\n\n\t\tconst newInlineStyles = cachedStyles.filter(el => {\n\t\t\t// no el.href, assume it's an inline style\n\t\t\tif (!el.href) {\n\t\t\t\treturn true\n\t\t\t} else if (!currentStyles.find((link) => link.href === el.href)) {\n\t\t\t\tdocument.body.append(el)\n\t\t\t\treturn false\n\t\t\t}\n\t\t})\n\n\t\t// loop through all new inline styles\n\t\tfor (let i = 0; i < currentInlineStyles.length; i++) {\n\t\t\tfor (let n = 0; n < newInlineStyles.length; n++) {\n\t\t\t\tif (currentInlineStyles[i].outerHTML === newInlineStyles[n].outerHTML) {\n\t\t\t\t\treloadElement(currentInlineStyles[i], 'STYLE')\n\t\t\t\t\tnewInlineStyles.splice(n, 1)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tfor (const style of newInlineStyles) {\n\t\t\tappendElement(style, 'STYLE')\n\t\t}\n\t}\n\n\t/**\n\t * @private\n\t * @param {string} links\n\t */\n\tattachEvents(links) {\n\t\tE.delegate('click', links, this.onClick)\n\t\tE.on('popstate', window, this.onPopstate)\n\n\t\tif (this.enablePrefetch) {\n\t\t\tE.delegate('mouseenter focus', links, this.onPrefetch)\n\t\t}\n\t}\n\n\t/**\n\t * @private\n\t * @param {MouseEvent} e\n\t */\n\tonClick = (e) => {\n\t\tif (!(e.metaKey || e.ctrlKey)) {\n\t\t\tconst target = processUrl(e.currentTarget.href)\n\t\t\tthis.currentLocation = processUrl(window.location.href)\n\n\t\t\tif (this.currentLocation.host !== target.host) {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// the target is a new URL, or is removing the hash from the current URL\n\t\t\tif (this.currentLocation.href !== target.href || (this.currentLocation.hasHash && !target.hasHash)) {\n\t\t\t\te.preventDefault()\n\t\t\t\t// noinspection JSIgnoredPromiseFromCall\n\t\t\t\tthis.navigateTo(target.raw, e.currentTarget.dataset.transition || false, e.currentTarget).catch(err => console.warn(err))\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// a click to the current URL was detected\n\t\t\tif (!this.currentLocation.hasHash && !target.hasHash) {\n\t\t\t\te.preventDefault()\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * @private\n\t * @return {void|boolean}\n\t */\n\tonPopstate = () => {\n\t\t// don't trigger for on-page anchors\n\t\tif (window.location.pathname === this.currentLocation.pathname && !this.isPopping) {\n\t\t\treturn false\n\t\t}\n\n\t\tif (!this.allowInterruption && (this.isTransitioning || this.isPopping)) {\n\t\t\t// overwrite history state with current page if currently navigating\n\t\t\twindow.history.pushState({}, '', this.popTarget)\n\t\t\tconsole.warn(IN_PROGRESS)\n\t\t\treturn false\n\t\t}\n\n\t\tif (!this.isPopping) {\n\t\t\tthis.popTarget = window.location.href\n\t\t}\n\n\t\tthis.isPopping = true\n\n\t\t// noinspection JSIgnoredPromiseFromCall\n\t\tthis.navigateTo(window.location.href, false, 'popstate')\n\t}\n\n\t/**\n\t * @private\n\t * @param {MouseEvent} e\n\t */\n\tonPrefetch = (e) => {\n\t\tconst target = processUrl(e.currentTarget.href)\n\n\t\tif (this.currentLocation.host !== target.host) {\n\t\t\treturn\n\t\t}\n\n\t\tthis.preload(e.currentTarget.href, false)\n\t}\n\n\t/**\n\t * @private\n\t * @param {string} url\n\t * @param {boolean} [runFallback]\n\t * @return {Promise<{html: Document, url: string}>}\n\t */\n\tfetch(url, runFallback = true) {\n\t\t// If Taxi is currently performing a fetch for the given URL, return that instead of starting a new request\n\t\tif (this.activePromises.has(url)) {\n\t\t\treturn this.activePromises.get(url)\n\t\t}\n\n\t\tconst request = new Promise((resolve, reject) => {\n\t\t\tlet resolvedUrl\n\n\t\t\tfetch(url, {\n\t\t\t\tmode: 'same-origin',\n\t\t\t\tmethod: 'GET',\n\t\t\t\theaders: { 'X-Requested-With': 'Taxi' },\n\t\t\t\tcredentials: 'same-origin'\n\t\t\t})\n\t\t\t\t.then((response) => {\n\t\t\t\t\tif (!response.ok) {\n\t\t\t\t\t\treject('Taxi encountered a non 2xx HTTP status code')\n\n\t\t\t\t\t\tif (runFallback) {\n\t\t\t\t\t\t\twindow.location.href = url\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tresolvedUrl = response.url\n\n\t\t\t\t\treturn response.text()\n\t\t\t\t})\n\t\t\t\t.then((htmlString) => {\n\t\t\t\t\tresolve({ html: parseDom(htmlString), url: resolvedUrl })\n\t\t\t\t})\n\t\t\t\t.catch((err) => {\n\t\t\t\t\treject(err)\n\n\t\t\t\t\tif (runFallback) {\n\t\t\t\t\t\twindow.location.href = url\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\t.finally(() => {\n\t\t\t\t\tthis.activePromises.delete(url)\n\t\t\t\t})\n\t\t})\n\n\t\tthis.activePromises.set(url, request)\n\n\t\treturn request\n\t}\n\n\t/**\n\t * @private\n\t * @param {string|false} transition\n\t * @return {Transition|function}\n\t */\n\tchooseTransition(transition) {\n\t\tif (transition) {\n\t\t\treturn this.transitions[transition]\n\t\t}\n\n\t\tconst routeTransition = this.router?.findMatch(this.currentLocation, this.targetLocation)\n\n\t\tif (routeTransition) {\n\t\t\treturn this.transitions[routeTransition]\n\t\t}\n\n\t\treturn this.defaultTransition\n\t}\n\n\t/**\n\t * @private\n\t * @param {Document|Node} page\n\t * @param {string} url\n\t * @return {CacheEntry}\n\t */\n\tcreateCacheEntry(page, url) {\n\t\tconst content = page.querySelector('[data-taxi-view]')\n\t\tconst Renderer = content.dataset.taxiView.length ? this.renderers[content.dataset.taxiView] : this.defaultRenderer\n\n\t\tif (!Renderer) {\n\t\t\tconsole.warn(`The Renderer \"${content.dataset.taxiView}\" was set in the data-taxi-view of the requested page, but not registered in Taxi.`)\n\t\t}\n\n\t\treturn {\n\t\t\tpage,\n\t\t\tcontent,\n\t\t\tfinalUrl: url,\n\t\t\tskipCache: content.hasAttribute('data-taxi-nocache'),\n\t\t\tscripts: this.reloadJsFilter ? Array.from(page.querySelectorAll('script')).filter(this.reloadJsFilter) : [],\n\t\t\tstyles: this.reloadCssFilter ? Array.from(page.querySelectorAll('link[rel=\"stylesheet\"], style')).filter(this.reloadCssFilter) : [],\n\t\t\ttitle: page.title,\n\t\t\trenderer: new Renderer({\n\t\t\t\twrapper: this.wrapper,\n\t\t\t\ttitle: page.title,\n\t\t\t\tcontent,\n\t\t\t\tpage\n\t\t\t})\n\t\t}\n\t}\n}\n"],"names":["parser","DOMParser","processUrl","url","details","URL","window","location","origin","normalized","hash","length","replace","hasHash","pathname","host","raw","href","reloadElement","node","elementType","parentNode","replaceChild","duplicateElement","appendElement","tagName","document","head","body","appendChild","replacement","createElement","k","attributes","attr","setAttribute","nodeName","nodeValue","innerHTML","Transition","constructor","wrapper","this","leave","props","Promise","resolve","onLeave","done","enter","onEnter","Renderer","content","page","title","_contentString","outerHTML","_DOM","lastElementChild","onEnterCompleted","onLeaveCompleted","initialLoad","update","firstElementChild","createDom","remove","transition","trigger","to","then","removeOldContent","from","RouteStore","data","Map","regexCache","add","fromPattern","toPattern","has","set","RegExp","get","findMatch","currentUrl","nextUrl","potentialMatches","match","IN_PROGRESS","Core","parameters","isTransitioning","currentCacheEntry","cache","activePromises","onClick","e","metaKey","ctrlKey","target","currentTarget","currentLocation","preventDefault","navigateTo","dataset","catch","err","console","warn","onPopstate","isPopping","allowInterruption","popTarget","history","pushState","onPrefetch","preload","links","bypassCache","enablePrefetch","renderers","default","transitions","reloadJsFilter","element","undefined","taxiReload","reloadCssFilter","defaultRenderer","defaultTransition","querySelector","attachEvents","createCacheEntry","cloneNode","renderer","setDefaultRenderer","setDefaultTransition","addRoute","router","preloadAssets","fetch","async","response","_this","html","updateCache","key","delete","clearCache","reject","Error","targetLocation","TransitionClass","chooseTransition","navigationPromise","skipCache","fetched","beforeFetch","_this2","afterFetch","on","event","callback","E","off","emit","entry","loadScripts","scripts","loadStyles","styles","finalUrl","replaceState","cachedScripts","newScripts","currentScripts","Array","querySelectorAll","filter","i","n","splice","script","cachedStyles","currentStyles","currentInlineStyles","newInlineStyles","el","find","link","append","style","delegate","runFallback","request","resolvedUrl","mode","method","headers","credentials","ok","text","htmlString","parseFromString","finally","routeTransition","_this$router","taxiView","hasAttribute"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"taxi.modern.js","sources":["../src/helpers.js","../src/Transition.js","../src/Renderer.js","../src/RouteStore.js","../src/Core.js"],"sourcesContent":["const parser = new DOMParser()\n\n/**\n * Parse a HTML string into a proper Document.\n *\n * @param {string|Document} html\n * @return {Document|*}\n */\nexport function parseDom(html) {\n\treturn typeof html === 'string' ? parser.parseFromString(html, 'text/html') : html\n}\n\n/**\n * Extract details from a given URL string. Assumed to be on the current TLD.\n *\n * @param {string} url\n * @return {{raw: string, href: string, host: string, search: string, hasHash: boolean, pathname: string}}\n */\nexport function processUrl(url) {\n\tconst details = new URL(url, window.location.origin)\n\tconst normalized = details.hash.length ? url.replace(details.hash, '') : null\n\n\treturn {\n\t\thasHash: details.hash.length > 0,\n\t\tpathname: details.pathname,\n\t\thost: details.host,\n\t\tsearch: details.search,\n\t\traw: url,\n\t\thref: normalized || details.href\n\t}\n}\n\n/**\n * Reloads a provided script/stylesheet by replacing with itself.\n *\n * @param {HTMLElement|HTMLScriptElement|HTMLStyleElement} node\n * @param {string} elementType - 'SCRIPT' or 'STYLE'\n */\nexport function reloadElement(node, elementType) {\n\tnode.parentNode.replaceChild(duplicateElement(node, elementType), node)\n}\n\n/**\n * Loads a provided script/stylesheet by appending a clone to the current document.\n *\n * @param {HTMLElement|HTMLStyleElement} node\n * @param {string} elementType - 'SCRIPT' or 'STYLE'\n */\nexport function appendElement(node, elementType) {\n\tconst target = node.parentNode.tagName === 'HEAD' ? document.head : document.body\n\ttarget.appendChild(duplicateElement(node, elementType))\n}\n\n/**\n * Creates a clone of a given HTMLElement or HTMLStyleElement\n *\n * @param {HTMLElement|HTMLStyleElement} node\n * @param {string} elementType - 'SCRIPT' or 'STYLE'\n * @return {HTMLElement|HTMLStyleElement}\n */\nexport function duplicateElement(node, elementType) {\n\tconst replacement = document.createElement(elementType)\n\n\tfor (let k = 0; k < node.attributes.length; k++) {\n\t\tconst attr = node.attributes[k]\n\t\treplacement.setAttribute(attr.nodeName, attr.nodeValue)\n\t}\n\n\t// Inline Script or Style\n\tif (node.innerHTML) {\n\t\treplacement.innerHTML = node.innerHTML\n\t}\n\n\treturn replacement\n}\n","export default class Transition {\n\t/**\n\t * @param {{wrapper: HTMLElement}} props\n\t */\n\tconstructor({ wrapper }) {\n\t\tthis.wrapper = wrapper\n\t}\n\n\t/**\n\t * @param {{ from: HTMLElement|Element, trigger: string|HTMLElement|false }} props\n\t * @return {Promise}\n\t */\n\tleave(props) {\n\t\treturn new Promise((resolve) => {\n\t\t\tthis.onLeave({ ...props, done: resolve })\n\t\t})\n\t}\n\n\t/**\n\t * @param {{ to: HTMLElement|Element, trigger: string|HTMLElement|false }} props\n\t * @return {Promise}\n\t */\n\tenter(props) {\n\t\treturn new Promise((resolve) => {\n\t\t\tthis.onEnter({ ...props, done: resolve })\n\t\t})\n\t}\n\n\t/**\n\t * Handle the transition leaving the previous page.\n\t * @param {{from: HTMLElement|Element, trigger: string|HTMLElement|false, done: function}} props\n\t */\n\tonLeave({ from, trigger, done }) {\n\t\tdone()\n\t}\n\n\t/**\n\t * Handle the transition entering the next page.\n\t * @param {{to: HTMLElement|Element, trigger: string|HTMLElement|false, done: function}} props\n\t */\n\tonEnter({ to, trigger, done }) {\n\t\tdone()\n\t}\n}\n","import Transition from \"./Transition\"\n\nexport default class Renderer {\n\t/**\n\t * @param {{content: HTMLElement|Element, page: Document|Node, title: string, wrapper: Element}} props\n\t */\n\tconstructor({ content, page, title, wrapper }) {\n\t\tthis._contentString = content.outerHTML\n\t\tthis._DOM = null\n\t\tthis.page = page\n\t\tthis.title = title\n\t\tthis.wrapper = wrapper\n\t\tthis.content = this.wrapper.lastElementChild\n\t}\n\n\tonEnter() {\n\n\t}\n\n\tonEnterCompleted() {\n\n\t}\n\n\tonLeave() {\n\n\t}\n\n\tonLeaveCompleted() {\n\n\t}\n\n\tinitialLoad() {\n\t\tthis.onEnter()\n\t\tthis.onEnterCompleted()\n\t}\n\n\tupdate() {\n\t\tdocument.title = this.title\n\t\tthis.wrapper.appendChild(this._DOM.firstElementChild)\n\t\tthis.content = this.wrapper.lastElementChild\n\t\tthis._DOM = null\n\t}\n\n\tcreateDom() {\n\t\tif (!this._DOM) {\n\t\t\tthis._DOM = document.createElement('div')\n\t\t\tthis._DOM.innerHTML = this._contentString\n\t\t}\n\t}\n\n\tremove() {\n\t\tthis.wrapper.firstElementChild.remove()\n\t}\n\n\t/**\n\t * Called when transitioning into the current page.\n\t * @param {Transition} transition\n\t * @param {string|HTMLElement|false} trigger\n\t * @return {Promise}\n\t */\n\tenter(transition, trigger) {\n\t\treturn new Promise((resolve) => {\n\t\t\tthis.onEnter()\n\n\t\t\ttransition.enter({ trigger, to: this.content })\n\t\t\t\t.then(() => {\n\t\t\t\t\tthis.onEnterCompleted()\n\t\t\t\t\tresolve()\n\t\t\t\t})\n\t\t})\n\t}\n\n\t/**\n\t * Called when transitioning away from the current page.\n\t * @param {Transition} transition\n\t * @param {string|HTMLElement|false} trigger\n\t * @param {boolean} removeOldContent\n\t * @return {Promise}\n\t */\n\tleave(transition, trigger, removeOldContent) {\n\t\treturn new Promise((resolve) => {\n\t\t\tthis.onLeave()\n\n\t\t\ttransition.leave({ trigger, from: this.content })\n\t\t\t\t.then(() => {\n\t\t\t\t\tif (removeOldContent) {\n\t\t\t\t\t\tthis.remove()\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.onLeaveCompleted()\n\t\t\t\t\tresolve()\n\t\t\t\t})\n\t\t})\n\t}\n}\n","export default class RouteStore {\n\t/**\n\t * @type {Map>}\n\t */\n\tdata = new Map()\n\n\t/**\n\t * @type {Map}\n\t */\n\tregexCache = new Map()\n\n\t/**\n\t *\n\t * @param {string} fromPattern\n\t * @param {string} toPattern\n\t * @param {string} transition\n\t */\n\tadd(fromPattern, toPattern, transition) {\n\t\tif (!this.data.has(fromPattern)) {\n\t\t\tthis.data.set(fromPattern, new Map())\n\t\t\tthis.regexCache.set(fromPattern, new RegExp(`^${fromPattern}$`))\n\t\t}\n\n\t\tthis.data.get(fromPattern).set(toPattern, transition)\n\t\tthis.regexCache.set(toPattern, new RegExp(`^${toPattern}$`))\n\t}\n\n\t/**\n\t *\n\t * @param {{ raw: string, href: string, hasHash: boolean, pathname: string }} currentUrl\n\t * @param {{ raw: string, href: string, hasHash: boolean, pathname: string }} nextUrl\n\t * @return {string|null}\n\t */\n\tfindMatch(currentUrl, nextUrl) {\n\t\t// Loop through all from patterns\n\t\tfor (const [fromPattern, potentialMatches] of this.data) {\n\t\t\t// If we have a match\n\t\t\tif (currentUrl.pathname.match(this.regexCache.get(fromPattern))) {\n\t\t\t\t// loop through all associated to patterns\n\t\t\t\tfor (const [toPattern, transition] of potentialMatches) {\n\t\t\t\t\t// If we find a match, return it\n\t\t\t\t\tif (nextUrl.pathname.match(this.regexCache.get(toPattern))) {\n\t\t\t\t\t\treturn transition\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\treturn null\n\t}\n}\n","import E from '@unseenco/e'\nimport { appendElement, parseDom, processUrl, reloadElement } from './helpers'\nimport Transition from './Transition'\nimport Renderer from './Renderer'\nimport RouteStore from './RouteStore'\n\nconst IN_PROGRESS = 'A transition is currently in progress'\n\n/**\n * @typedef CacheEntry\n * @type {object}\n * @property {typeof Renderer|Renderer} renderer\n * @property {Document|Node} page\n * @property {array} scripts\n * @property {HTMLLinkElement[]} styles\n * @property {string} finalUrl\n * @property {boolean} skipCache\n * @property {string} title\n * @property {HTMLElement|Element} content\n */\n\nexport default class Core {\n\tisTransitioning = false\n\n\t/**\n\t * @type {CacheEntry|null}\n\t */\n\tcurrentCacheEntry = null\n\n\t/**\n\t * @type {Map}\n\t */\n\tcache = new Map()\n\n\t/**\n\t * @private\n\t * @type {Map}\n\t */\n\tactivePromises = new Map()\n\n\t/**\n\t * @param {{\n\t * \t\tlinks?: string,\n\t * \t\tremoveOldContent?: boolean,\n\t * \t\tallowInterruption?: boolean,\n\t * \t\tbypassCache?: boolean,\n\t * \t\tenablePrefetch?: boolean,\n\t * \t\trenderers?: Object.,\n\t * \t\ttransitions?: Object.,\n\t * \t\treloadJsFilter?: boolean|function(HTMLElement): boolean,\n\t * \t\treloadCssFilter?: boolean|function(HTMLLinkElement): boolean\n\t * }} parameters\n\t */\n\tconstructor(parameters = {}) {\n\t\tconst {\n\t\t\tlinks = 'a:not([target]):not([href^=\\\\#]):not([data-taxi-ignore])',\n\t\t\tremoveOldContent = true,\n\t\t\tallowInterruption = false,\n\t\t\tbypassCache = false,\n\t\t\tenablePrefetch = true,\n\t\t\trenderers = {\n\t\t\t\tdefault: Renderer\n\t\t\t},\n\t\t\ttransitions = {\n\t\t\t\tdefault: Transition\n\t\t\t},\n\t\t\treloadJsFilter = (element) => element.dataset.taxiReload !== undefined,\n\t\t\treloadCssFilter = (element) => true //element.dataset.taxiReload !== undefined\n\t\t} = parameters\n\n\t\tthis.renderers = renderers\n\t\tthis.transitions = transitions\n\t\tthis.defaultRenderer = this.renderers.default || Renderer\n\t\tthis.defaultTransition = this.transitions.default || Transition\n\t\tthis.wrapper = document.querySelector('[data-taxi]')\n\t\tthis.reloadJsFilter = reloadJsFilter\n\t\tthis.reloadCssFilter = reloadCssFilter\n\t\tthis.removeOldContent = removeOldContent\n\t\tthis.allowInterruption = allowInterruption\n\t\tthis.bypassCache = bypassCache\n\t\tthis.enablePrefetch = enablePrefetch\n\t\tthis.cache = new Map()\n\t\tthis.isPopping = false\n\n\t\t// Add delegated link events\n\t\tthis.attachEvents(links)\n\n\t\tthis.currentLocation = processUrl(window.location.href)\n\n\t\t// as this is the initial page load, prime this page into the cache\n\t\tthis.cache.set(this.currentLocation.href, this.createCacheEntry(document.cloneNode(true), window.location.href))\n\n\t\t// fire the current Renderer enter methods\n\t\tthis.currentCacheEntry = this.cache.get(this.currentLocation.href)\n\t\tthis.currentCacheEntry.renderer.initialLoad()\n\t}\n\n\t/**\n\t * @param {string} renderer\n\t */\n\tsetDefaultRenderer(renderer) {\n\t\tthis.defaultRenderer = this.renderers[renderer]\n\t}\n\n\t/**\n\t * @param {string} transition\n\t */\n\tsetDefaultTransition(transition) {\n\t\tthis.defaultTransition = this.transitions[transition]\n\t}\n\n\t/**\n\t * Registers a route into the RouteStore\n\t *\n\t * @param {string} fromPattern\n\t * @param {string} toPattern\n\t * @param {string} transition\n\t */\n\taddRoute(fromPattern, toPattern, transition) {\n\t\tif (!this.router) {\n\t\t\tthis.router = new RouteStore()\n\t\t}\n\n\t\tthis.router.add(fromPattern, toPattern, transition)\n\t}\n\n\t/**\n\t * Prime the cache for a given URL\n\t *\n\t * @param {string} url\n\t * @param {boolean} [preloadAssets]\n\t * @return {Promise}\n\t */\n\tpreload(url, preloadAssets = false) {\n\t\t// convert relative URLs to absolute\n\t\turl = processUrl(url).href\n\n\t\tif (!this.cache.has(url)) {\n\t\t\treturn this.fetch(url, false)\n\t\t\t\t.then(async (response) => {\n\t\t\t\t\tthis.cache.set(url, this.createCacheEntry(response.html, response.url))\n\n\t\t\t\t\tif (preloadAssets) {\n\t\t\t\t\t\tthis.cache.get(url).renderer.createDom()\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\t.catch(err => console.warn(err))\n\t\t}\n\n\t\treturn Promise.resolve()\n\t}\n\n\t/**\n\t * Updates the HTML cache for a given URL.\n\t * If no URL is passed, then cache for the current page is updated.\n\t * Useful when adding/removing content via AJAX such as a search page or infinite loader.\n\t *\n\t * @param {string} [url]\n\t */\n\tupdateCache(url) {\n\t\tconst key = processUrl(url || window.location.href).href\n\n\t\tif (this.cache.has(key)) {\n\t\t\tthis.cache.delete(key)\n\t\t}\n\n\t\tthis.cache.set(key, this.createCacheEntry(document.cloneNode(true), key))\n\t}\n\n\t/**\n\t * Clears the cache for a given URL.\n\t * If no URL is passed, then cache for the current page is cleared.\n\t *\n\t * @param {string} [url]\n\t */\n\tclearCache(url) {\n\t\tconst key = processUrl(url || window.location.href).href\n\n\t\tif (this.cache.has(key)) {\n\t\t\tthis.cache.delete(key)\n\t\t}\n\t}\n\n\t/**\n\t * @param {string} url\n\t * @param {string|false} [transition]\n\t * @param {string|false|HTMLElement} [trigger]\n\t * @return {Promise}\n\t */\n\tnavigateTo(url, transition = false, trigger = false) {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\t// Don't allow multiple navigations to occur at once\n\t\t\tif (!this.allowInterruption && this.isTransitioning) {\n\t\t\t\treject(new Error(IN_PROGRESS))\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tthis.isTransitioning = true\n\t\t\tthis.isPopping = true\n\t\t\tthis.targetLocation = processUrl(url)\n\t\t\tthis.popTarget = window.location.href\n\n\t\t\tconst TransitionClass = new (this.chooseTransition(transition))({ wrapper: this.wrapper })\n\n\t\t\tlet navigationPromise\n\n\t\t\tif (this.bypassCache || !this.cache.has(this.targetLocation.href) || this.cache.get(this.targetLocation.href).skipCache) {\n\t\t\t\tconst fetched = this.fetch(this.targetLocation.href)\n\t\t\t\t\t.then((response) => {\n\t\t\t\t\t\tthis.cache.set(this.targetLocation.href, this.createCacheEntry(response.html, response.url))\n\t\t\t\t\t\tthis.cache.get(this.targetLocation.href).renderer.createDom()\n\t\t\t\t\t})\n\t\t\t\t\t.catch(err => {\n\t\t\t\t\t\t// we encountered a 4** or 5** error, redirect to the requested URL\n\t\t\t\t\t\twindow.location.href = url\n\t\t\t\t\t})\n\n\t\t\t\tnavigationPromise = this.beforeFetch(this.targetLocation, TransitionClass, trigger)\n\t\t\t\t\t.then(async () => {\n\t\t\t\t\t\treturn fetched.then(async () => {\n\t\t\t\t\t\t\treturn await this.afterFetch(this.targetLocation, TransitionClass, this.cache.get(this.targetLocation.href), trigger)\n\t\t\t\t\t\t})\n\t\t\t\t\t})\n\t\t\t} else {\n\t\t\t\tthis.cache.get(this.targetLocation.href).renderer.createDom()\n\n\t\t\t\tnavigationPromise = this.beforeFetch(this.targetLocation, TransitionClass, trigger)\n\t\t\t\t\t.then(async () => {\n\t\t\t\t\t\treturn await this.afterFetch(this.targetLocation, TransitionClass, this.cache.get(this.targetLocation.href), trigger)\n\t\t\t\t\t})\n\t\t\t}\n\n\t\t\tnavigationPromise.then(() => {\n\t\t\t\tresolve()\n\t\t\t})\n\t\t})\n\t}\n\n\t/**\n\t * Add an event listener.\n\t * @param {string} event\n\t * @param {any} callback\n\t */\n\ton(event, callback) {\n\t\tE.on(event, callback)\n\t}\n\n\t/**\n\t * Remove an event listener.\n\t * @param {string} event\n\t * @param {any} [callback]\n\t */\n\toff(event, callback) {\n\t\tE.off(event, callback)\n\t}\n\n\t/**\n\t * @private\n\t * @param {{ raw: string, href: string, hasHash: boolean, pathname: string }} url\n\t * @param {Transition} TransitionClass\n\t * @param {string|HTMLElement|false} trigger\n\t * @return {Promise}\n\t */\n\tbeforeFetch(url, TransitionClass, trigger) {\n\t\tE.emit('NAVIGATE_OUT', {\n\t\t\tfrom: this.currentCacheEntry,\n\t\t\ttrigger\n\t\t})\n\n\t\treturn new Promise((resolve) => {\n\t\t\tthis.currentCacheEntry.renderer.leave(TransitionClass, trigger, this.removeOldContent)\n\t\t\t\t.then(() => {\n\t\t\t\t\tif (trigger !== 'popstate') {\n\t\t\t\t\t\twindow.history.pushState({}, '', url.raw)\n\t\t\t\t\t}\n\n\t\t\t\t\tresolve()\n\t\t\t\t})\n\t\t})\n\t}\n\n\t/**\n\t * @private\n\t * @param {{ raw: string, href: string, host: string, hasHash: boolean, pathname: string }} url\n\t * @param {Transition} TransitionClass\n\t * @param {CacheEntry} entry\n\t * @param {string|HTMLElement|false} trigger\n\t * @return {Promise}\n\t */\n\tafterFetch(url, TransitionClass, entry, trigger) {\n\t\tthis.currentLocation = url\n\t\tthis.popTarget = this.currentLocation.href\n\n\t\treturn new Promise((resolve) => {\n\t\t\tentry.renderer.update()\n\n\t\t\tE.emit('NAVIGATE_IN', {\n\t\t\t\tfrom: this.currentCacheEntry,\n\t\t\t\tto: entry,\n\t\t\t\ttrigger\n\t\t\t})\n\n\t\t\tif (this.reloadJsFilter) {\n\t\t\t\tthis.loadScripts(entry.scripts)\n\t\t\t}\n\n\t\t\tif (this.reloadCssFilter) {\n\t\t\t\tthis.loadStyles(entry.styles)\n\t\t\t}\n\n\t\t\t// If the fetched url had a redirect chain, then replace the history to reflect the final resolved URL\n\t\t\tif (trigger !== 'popstate' && url.href !== entry.finalUrl) {\n\t\t\t\twindow.history.replaceState({}, '', entry.finalUrl)\n\t\t\t}\n\n\t\t\tentry.renderer.enter(TransitionClass, trigger)\n\t\t\t\t.then(() => {\n\t\t\t\t\tE.emit('NAVIGATE_END', {\n\t\t\t\t\t\tfrom: this.currentCacheEntry,\n\t\t\t\t\t\tto: entry,\n\t\t\t\t\t\ttrigger\n\t\t\t\t\t})\n\n\t\t\t\t\tthis.currentCacheEntry = entry\n\t\t\t\t\tthis.isTransitioning = false\n\t\t\t\t\tthis.isPopping = false\n\t\t\t\t\tresolve()\n\t\t\t\t})\n\t\t})\n\t}\n\n\t/**\n\t * Load up scripts from the target page if needed\n\t *\n\t * @param {HTMLElement[]} cachedScripts\n\t */\n\tloadScripts(cachedScripts) {\n\t\tconst newScripts = [...cachedScripts]\n\t\tconst currentScripts = Array.from(document.querySelectorAll('script')).filter(this.reloadJsFilter)\n\n\t\t// loop through all new scripts\n\t\tfor (let i = 0; i < currentScripts.length; i++) {\n\t\t\tfor (let n = 0; n < newScripts.length; n++) {\n\t\t\t\tif (currentScripts[i].outerHTML === newScripts[n].outerHTML) {\n\t\t\t\t\treloadElement(currentScripts[i], 'SCRIPT')\n\t\t\t\t\tnewScripts.splice(n, 1)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tfor (const script of newScripts) {\n\t\t\tappendElement(script, 'SCRIPT')\n\t\t}\n\t}\n\n\t/**\n\t * Load up styles from the target page if needed\n\t *\n\t * @param {Array} cachedStyles\n\t */\n\tloadStyles(cachedStyles) {\n\t\tconst currentStyles = Array.from(document.querySelectorAll('link[rel=\"stylesheet\"]')).filter(this.reloadCssFilter)\n\t\tconst currentInlineStyles = Array.from(document.querySelectorAll('style')).filter(this.reloadCssFilter)\n\n\t\tconst newInlineStyles = cachedStyles.filter(el => {\n\t\t\t// no el.href, assume it's an inline style\n\t\t\tif (!el.href) {\n\t\t\t\treturn true\n\t\t\t} else if (!currentStyles.find((link) => link.href === el.href)) {\n\t\t\t\tdocument.body.append(el)\n\t\t\t\treturn false\n\t\t\t}\n\t\t})\n\n\t\t// loop through all new inline styles\n\t\tfor (let i = 0; i < currentInlineStyles.length; i++) {\n\t\t\tfor (let n = 0; n < newInlineStyles.length; n++) {\n\t\t\t\tif (currentInlineStyles[i].outerHTML === newInlineStyles[n].outerHTML) {\n\t\t\t\t\treloadElement(currentInlineStyles[i], 'STYLE')\n\t\t\t\t\tnewInlineStyles.splice(n, 1)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tfor (const style of newInlineStyles) {\n\t\t\tappendElement(style, 'STYLE')\n\t\t}\n\t}\n\n\t/**\n\t * @private\n\t * @param {string} links\n\t */\n\tattachEvents(links) {\n\t\tE.delegate('click', links, this.onClick)\n\t\tE.on('popstate', window, this.onPopstate)\n\n\t\tif (this.enablePrefetch) {\n\t\t\tE.delegate('mouseenter focus', links, this.onPrefetch)\n\t\t}\n\t}\n\n\t/**\n\t * @private\n\t * @param {MouseEvent} e\n\t */\n\tonClick = (e) => {\n\t\tif (!(e.metaKey || e.ctrlKey)) {\n\t\t\tconst target = processUrl(e.currentTarget.href)\n\t\t\tthis.currentLocation = processUrl(window.location.href)\n\n\t\t\tif (this.currentLocation.host !== target.host) {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// the target is a new URL, or is removing the hash from the current URL\n\t\t\tif (this.currentLocation.href !== target.href || (this.currentLocation.hasHash && !target.hasHash)) {\n\t\t\t\te.preventDefault()\n\t\t\t\t// noinspection JSIgnoredPromiseFromCall\n\t\t\t\tthis.navigateTo(target.raw, e.currentTarget.dataset.transition || false, e.currentTarget).catch(err => console.warn(err))\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// a click to the current URL was detected\n\t\t\tif (!this.currentLocation.hasHash && !target.hasHash) {\n\t\t\t\te.preventDefault()\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * @private\n\t * @return {void|boolean}\n\t */\n\tonPopstate = () => {\n\t\t// don't trigger for on-page anchors\n\t\tif (\n\t\t\twindow.location.pathname === this.currentLocation.pathname\n\t\t\t&& window.location.search === this.currentLocation.search\n\t\t\t&& !this.isPopping\n\t\t) {\n\t\t\treturn false\n\t\t}\n\n\t\tif (!this.allowInterruption && (this.isTransitioning || this.isPopping)) {\n\t\t\t// overwrite history state with current page if currently navigating\n\t\t\twindow.history.pushState({}, '', this.popTarget)\n\t\t\tconsole.warn(IN_PROGRESS)\n\t\t\treturn false\n\t\t}\n\n\t\tif (!this.isPopping) {\n\t\t\tthis.popTarget = window.location.href\n\t\t}\n\n\t\tthis.isPopping = true\n\n\t\t// noinspection JSIgnoredPromiseFromCall\n\t\tthis.navigateTo(window.location.href, false, 'popstate')\n\t}\n\n\t/**\n\t * @private\n\t * @param {MouseEvent} e\n\t */\n\tonPrefetch = (e) => {\n\t\tconst target = processUrl(e.currentTarget.href)\n\n\t\tif (this.currentLocation.host !== target.host) {\n\t\t\treturn\n\t\t}\n\n\t\tthis.preload(e.currentTarget.href, false)\n\t}\n\n\t/**\n\t * @private\n\t * @param {string} url\n\t * @param {boolean} [runFallback]\n\t * @return {Promise<{html: Document, url: string}>}\n\t */\n\tfetch(url, runFallback = true) {\n\t\t// If Taxi is currently performing a fetch for the given URL, return that instead of starting a new request\n\t\tif (this.activePromises.has(url)) {\n\t\t\treturn this.activePromises.get(url)\n\t\t}\n\n\t\tconst request = new Promise((resolve, reject) => {\n\t\t\tlet resolvedUrl\n\n\t\t\tfetch(url, {\n\t\t\t\tmode: 'same-origin',\n\t\t\t\tmethod: 'GET',\n\t\t\t\theaders: { 'X-Requested-With': 'Taxi' },\n\t\t\t\tcredentials: 'same-origin'\n\t\t\t})\n\t\t\t\t.then((response) => {\n\t\t\t\t\tif (!response.ok) {\n\t\t\t\t\t\treject('Taxi encountered a non 2xx HTTP status code')\n\n\t\t\t\t\t\tif (runFallback) {\n\t\t\t\t\t\t\twindow.location.href = url\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tresolvedUrl = response.url\n\n\t\t\t\t\treturn response.text()\n\t\t\t\t})\n\t\t\t\t.then((htmlString) => {\n\t\t\t\t\tresolve({ html: parseDom(htmlString), url: resolvedUrl })\n\t\t\t\t})\n\t\t\t\t.catch((err) => {\n\t\t\t\t\treject(err)\n\n\t\t\t\t\tif (runFallback) {\n\t\t\t\t\t\twindow.location.href = url\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\t.finally(() => {\n\t\t\t\t\tthis.activePromises.delete(url)\n\t\t\t\t})\n\t\t})\n\n\t\tthis.activePromises.set(url, request)\n\n\t\treturn request\n\t}\n\n\t/**\n\t * @private\n\t * @param {string|false} transition\n\t * @return {Transition|function}\n\t */\n\tchooseTransition(transition) {\n\t\tif (transition) {\n\t\t\treturn this.transitions[transition]\n\t\t}\n\n\t\tconst routeTransition = this.router?.findMatch(this.currentLocation, this.targetLocation)\n\n\t\tif (routeTransition) {\n\t\t\treturn this.transitions[routeTransition]\n\t\t}\n\n\t\treturn this.defaultTransition\n\t}\n\n\t/**\n\t * @private\n\t * @param {Document|Node} page\n\t * @param {string} url\n\t * @return {CacheEntry}\n\t */\n\tcreateCacheEntry(page, url) {\n\t\tconst content = page.querySelector('[data-taxi-view]')\n\t\tconst Renderer = content.dataset.taxiView.length ? this.renderers[content.dataset.taxiView] : this.defaultRenderer\n\n\t\tif (!Renderer) {\n\t\t\tconsole.warn(`The Renderer \"${content.dataset.taxiView}\" was set in the data-taxi-view of the requested page, but not registered in Taxi.`)\n\t\t}\n\n\t\treturn {\n\t\t\tpage,\n\t\t\tcontent,\n\t\t\tfinalUrl: url,\n\t\t\tskipCache: content.hasAttribute('data-taxi-nocache'),\n\t\t\tscripts: this.reloadJsFilter ? Array.from(page.querySelectorAll('script')).filter(this.reloadJsFilter) : [],\n\t\t\tstyles: this.reloadCssFilter ? Array.from(page.querySelectorAll('link[rel=\"stylesheet\"], style')).filter(this.reloadCssFilter) : [],\n\t\t\ttitle: page.title,\n\t\t\trenderer: new Renderer({\n\t\t\t\twrapper: this.wrapper,\n\t\t\t\ttitle: page.title,\n\t\t\t\tcontent,\n\t\t\t\tpage\n\t\t\t})\n\t\t}\n\t}\n}\n"],"names":["parser","DOMParser","processUrl","url","details","URL","window","location","origin","normalized","hash","length","replace","hasHash","pathname","host","search","raw","href","reloadElement","node","elementType","parentNode","replaceChild","duplicateElement","appendElement","tagName","document","head","body","appendChild","replacement","createElement","k","attributes","attr","setAttribute","nodeName","nodeValue","innerHTML","Transition","constructor","wrapper","this","leave","props","Promise","resolve","onLeave","done","enter","onEnter","Renderer","content","page","title","_contentString","outerHTML","_DOM","lastElementChild","onEnterCompleted","onLeaveCompleted","initialLoad","update","firstElementChild","createDom","remove","transition","trigger","to","then","removeOldContent","from","RouteStore","data","Map","regexCache","add","fromPattern","toPattern","has","set","RegExp","get","findMatch","currentUrl","nextUrl","potentialMatches","match","IN_PROGRESS","Core","parameters","isTransitioning","currentCacheEntry","cache","activePromises","onClick","e","metaKey","ctrlKey","target","currentTarget","currentLocation","preventDefault","navigateTo","dataset","catch","err","console","warn","onPopstate","isPopping","allowInterruption","popTarget","history","pushState","onPrefetch","preload","links","bypassCache","enablePrefetch","renderers","default","transitions","reloadJsFilter","element","undefined","taxiReload","reloadCssFilter","defaultRenderer","defaultTransition","querySelector","attachEvents","createCacheEntry","cloneNode","renderer","setDefaultRenderer","setDefaultTransition","addRoute","router","preloadAssets","fetch","async","response","_this","html","updateCache","key","delete","clearCache","reject","Error","targetLocation","TransitionClass","chooseTransition","navigationPromise","skipCache","fetched","beforeFetch","_this2","afterFetch","on","event","callback","E","off","emit","entry","loadScripts","scripts","loadStyles","styles","finalUrl","replaceState","cachedScripts","newScripts","currentScripts","Array","querySelectorAll","filter","i","n","splice","script","cachedStyles","currentStyles","currentInlineStyles","newInlineStyles","el","find","link","append","style","delegate","runFallback","request","resolvedUrl","mode","method","headers","credentials","ok","text","htmlString","parseFromString","finally","routeTransition","_this$router","taxiView","hasAttribute"],"mappings":"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"} \ No newline at end of file diff --git a/dist/taxi.umd.js b/dist/taxi.umd.js index fd714c7..7a9f8bd 100644 --- a/dist/taxi.umd.js +++ b/dist/taxi.umd.js @@ -1,2 +1,2 @@ -!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("@unseenco/e")):"function"==typeof define&&define.amd?define(["exports","@unseenco/e"],t):t((e||self).taxi={},e.E)}(this,function(e,t){function r(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var n=/*#__PURE__*/r(t);function i(){return i=Object.assign||function(e){for(var t=1;te.length)&&(t=e.length);for(var r=0,n=new Array(t);r=e.length?{done:!0}:{done:!1,value:e[n++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var c=new DOMParser;function s(e){var t=new URL(e,window.location.origin),r=t.hash.length?e.replace(t.hash,""):null;return{hasHash:t.hash.length>0,pathname:t.pathname,host:t.host,raw:e,href:r||t.href}}function h(e,t){e.parentNode.replaceChild(l(e,t),e)}function u(e,t){("HEAD"===e.parentNode.tagName?document.head:document.body).appendChild(l(e,t))}function l(e,t){for(var r=document.createElement(t),n=0;ne.length)&&(t=e.length);for(var r=0,n=new Array(t);r=e.length?{done:!0}:{done:!1,value:e[n++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var c=new DOMParser;function s(e){var t=new URL(e,window.location.origin),r=t.hash.length?e.replace(t.hash,""):null;return{hasHash:t.hash.length>0,pathname:t.pathname,host:t.host,search:t.search,raw:e,href:r||t.href}}function h(e,t){e.parentNode.replaceChild(l(e,t),e)}function u(e,t){("HEAD"===e.parentNode.tagName?document.head:document.body).appendChild(l(e,t))}function l(e,t){for(var r=document.createElement(t),n=0;n 0,\n\t\tpathname: details.pathname,\n\t\thost: details.host,\n\t\traw: url,\n\t\thref: normalized || details.href\n\t}\n}\n\n/**\n * Reloads a provided script/stylesheet by replacing with itself.\n *\n * @param {HTMLElement|HTMLScriptElement|HTMLStyleElement} node\n * @param {string} elementType - 'SCRIPT' or 'STYLE'\n */\nexport function reloadElement(node, elementType) {\n\tnode.parentNode.replaceChild(duplicateElement(node, elementType), node)\n}\n\n/**\n * Loads a provided script/stylesheet by appending a clone to the current document.\n *\n * @param {HTMLElement|HTMLStyleElement} node\n * @param {string} elementType - 'SCRIPT' or 'STYLE'\n */\nexport function appendElement(node, elementType) {\n\tconst target = node.parentNode.tagName === 'HEAD' ? document.head : document.body\n\ttarget.appendChild(duplicateElement(node, elementType))\n}\n\n/**\n * Creates a clone of a given HTMLElement or HTMLStyleElement\n *\n * @param {HTMLElement|HTMLStyleElement} node\n * @param {string} elementType - 'SCRIPT' or 'STYLE'\n * @return {HTMLElement|HTMLStyleElement}\n */\nexport function duplicateElement(node, elementType) {\n\tconst replacement = document.createElement(elementType)\n\n\tfor (let k = 0; k < node.attributes.length; k++) {\n\t\tconst attr = node.attributes[k]\n\t\treplacement.setAttribute(attr.nodeName, attr.nodeValue)\n\t}\n\n\t// Inline Script or Style\n\tif (node.innerHTML) {\n\t\treplacement.innerHTML = node.innerHTML\n\t}\n\n\treturn replacement\n}\n","export default class Transition {\n\t/**\n\t * @param {{wrapper: HTMLElement}} props\n\t */\n\tconstructor({ wrapper }) {\n\t\tthis.wrapper = wrapper\n\t}\n\n\t/**\n\t * @param {{ from: HTMLElement|Element, trigger: string|HTMLElement|false }} props\n\t * @return {Promise}\n\t */\n\tleave(props) {\n\t\treturn new Promise((resolve) => {\n\t\t\tthis.onLeave({ ...props, done: resolve })\n\t\t})\n\t}\n\n\t/**\n\t * @param {{ to: HTMLElement|Element, trigger: string|HTMLElement|false }} props\n\t * @return {Promise}\n\t */\n\tenter(props) {\n\t\treturn new Promise((resolve) => {\n\t\t\tthis.onEnter({ ...props, done: resolve })\n\t\t})\n\t}\n\n\t/**\n\t * Handle the transition leaving the previous page.\n\t * @param {{from: HTMLElement|Element, trigger: string|HTMLElement|false, done: function}} props\n\t */\n\tonLeave({ from, trigger, done }) {\n\t\tdone()\n\t}\n\n\t/**\n\t * Handle the transition entering the next page.\n\t * @param {{to: HTMLElement|Element, trigger: string|HTMLElement|false, done: function}} props\n\t */\n\tonEnter({ to, trigger, done }) {\n\t\tdone()\n\t}\n}\n","import Transition from \"./Transition\"\n\nexport default class Renderer {\n\t/**\n\t * @param {{content: HTMLElement|Element, page: Document|Node, title: string, wrapper: Element}} props\n\t */\n\tconstructor({ content, page, title, wrapper }) {\n\t\tthis._contentString = content.outerHTML\n\t\tthis._DOM = null\n\t\tthis.page = page\n\t\tthis.title = title\n\t\tthis.wrapper = wrapper\n\t\tthis.content = this.wrapper.lastElementChild\n\t}\n\n\tonEnter() {\n\n\t}\n\n\tonEnterCompleted() {\n\n\t}\n\n\tonLeave() {\n\n\t}\n\n\tonLeaveCompleted() {\n\n\t}\n\n\tinitialLoad() {\n\t\tthis.onEnter()\n\t\tthis.onEnterCompleted()\n\t}\n\n\tupdate() {\n\t\tdocument.title = this.title\n\t\tthis.wrapper.appendChild(this._DOM.firstElementChild)\n\t\tthis.content = this.wrapper.lastElementChild\n\t\tthis._DOM = null\n\t}\n\n\tcreateDom() {\n\t\tif (!this._DOM) {\n\t\t\tthis._DOM = document.createElement('div')\n\t\t\tthis._DOM.innerHTML = this._contentString\n\t\t}\n\t}\n\n\tremove() {\n\t\tthis.wrapper.firstElementChild.remove()\n\t}\n\n\t/**\n\t * Called when transitioning into the current page.\n\t * @param {Transition} transition\n\t * @param {string|HTMLElement|false} trigger\n\t * @return {Promise}\n\t */\n\tenter(transition, trigger) {\n\t\treturn new Promise((resolve) => {\n\t\t\tthis.onEnter()\n\n\t\t\ttransition.enter({ trigger, to: this.content })\n\t\t\t\t.then(() => {\n\t\t\t\t\tthis.onEnterCompleted()\n\t\t\t\t\tresolve()\n\t\t\t\t})\n\t\t})\n\t}\n\n\t/**\n\t * Called when transitioning away from the current page.\n\t * @param {Transition} transition\n\t * @param {string|HTMLElement|false} trigger\n\t * @param {boolean} removeOldContent\n\t * @return {Promise}\n\t */\n\tleave(transition, trigger, removeOldContent) {\n\t\treturn new Promise((resolve) => {\n\t\t\tthis.onLeave()\n\n\t\t\ttransition.leave({ trigger, from: this.content })\n\t\t\t\t.then(() => {\n\t\t\t\t\tif (removeOldContent) {\n\t\t\t\t\t\tthis.remove()\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.onLeaveCompleted()\n\t\t\t\t\tresolve()\n\t\t\t\t})\n\t\t})\n\t}\n}\n","export default class RouteStore {\n\t/**\n\t * @type {Map>}\n\t */\n\tdata = new Map()\n\n\t/**\n\t * @type {Map}\n\t */\n\tregexCache = new Map()\n\n\t/**\n\t *\n\t * @param {string} fromPattern\n\t * @param {string} toPattern\n\t * @param {string} transition\n\t */\n\tadd(fromPattern, toPattern, transition) {\n\t\tif (!this.data.has(fromPattern)) {\n\t\t\tthis.data.set(fromPattern, new Map())\n\t\t\tthis.regexCache.set(fromPattern, new RegExp(`^${fromPattern}$`))\n\t\t}\n\n\t\tthis.data.get(fromPattern).set(toPattern, transition)\n\t\tthis.regexCache.set(toPattern, new RegExp(`^${toPattern}$`))\n\t}\n\n\t/**\n\t *\n\t * @param {{ raw: string, href: string, hasHash: boolean, pathname: string }} currentUrl\n\t * @param {{ raw: string, href: string, hasHash: boolean, pathname: string }} nextUrl\n\t * @return {string|null}\n\t */\n\tfindMatch(currentUrl, nextUrl) {\n\t\t// Loop through all from patterns\n\t\tfor (const [fromPattern, potentialMatches] of this.data) {\n\t\t\t// If we have a match\n\t\t\tif (currentUrl.pathname.match(this.regexCache.get(fromPattern))) {\n\t\t\t\t// loop through all associated to patterns\n\t\t\t\tfor (const [toPattern, transition] of potentialMatches) {\n\t\t\t\t\t// If we find a match, return it\n\t\t\t\t\tif (nextUrl.pathname.match(this.regexCache.get(toPattern))) {\n\t\t\t\t\t\treturn transition\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\treturn null\n\t}\n}\n","import E from '@unseenco/e'\nimport { appendElement, parseDom, processUrl, reloadElement } from './helpers'\nimport Transition from './Transition'\nimport Renderer from './Renderer'\nimport RouteStore from './RouteStore'\n\nconst IN_PROGRESS = 'A transition is currently in progress'\n\n/**\n * @typedef CacheEntry\n * @type {object}\n * @property {typeof Renderer|Renderer} renderer\n * @property {Document|Node} page\n * @property {array} scripts\n * @property {HTMLLinkElement[]} styles\n * @property {string} finalUrl\n * @property {boolean} skipCache\n * @property {string} title\n * @property {HTMLElement|Element} content\n */\n\nexport default class Core {\n\tisTransitioning = false\n\n\t/**\n\t * @type {CacheEntry|null}\n\t */\n\tcurrentCacheEntry = null\n\n\t/**\n\t * @type {Map}\n\t */\n\tcache = new Map()\n\n\t/**\n\t * @private\n\t * @type {Map}\n\t */\n\tactivePromises = new Map()\n\n\t/**\n\t * @param {{\n\t * \t\tlinks?: string,\n\t * \t\tremoveOldContent?: boolean,\n\t * \t\tallowInterruption?: boolean,\n\t * \t\tbypassCache?: boolean,\n\t * \t\tenablePrefetch?: boolean,\n\t * \t\trenderers?: Object.,\n\t * \t\ttransitions?: Object.,\n\t * \t\treloadJsFilter?: boolean|function(HTMLElement): boolean,\n\t * \t\treloadCssFilter?: boolean|function(HTMLLinkElement): boolean\n\t * }} parameters\n\t */\n\tconstructor(parameters = {}) {\n\t\tconst {\n\t\t\tlinks = 'a:not([target]):not([href^=\\\\#]):not([data-taxi-ignore])',\n\t\t\tremoveOldContent = true,\n\t\t\tallowInterruption = false,\n\t\t\tbypassCache = false,\n\t\t\tenablePrefetch = true,\n\t\t\trenderers = {\n\t\t\t\tdefault: Renderer\n\t\t\t},\n\t\t\ttransitions = {\n\t\t\t\tdefault: Transition\n\t\t\t},\n\t\t\treloadJsFilter = (element) => element.dataset.taxiReload !== undefined,\n\t\t\treloadCssFilter = (element) => true //element.dataset.taxiReload !== undefined\n\t\t} = parameters\n\n\t\tthis.renderers = renderers\n\t\tthis.transitions = transitions\n\t\tthis.defaultRenderer = this.renderers.default || Renderer\n\t\tthis.defaultTransition = this.transitions.default || Transition\n\t\tthis.wrapper = document.querySelector('[data-taxi]')\n\t\tthis.reloadJsFilter = reloadJsFilter\n\t\tthis.reloadCssFilter = reloadCssFilter\n\t\tthis.removeOldContent = removeOldContent\n\t\tthis.allowInterruption = allowInterruption\n\t\tthis.bypassCache = bypassCache\n\t\tthis.enablePrefetch = enablePrefetch\n\t\tthis.cache = new Map()\n\t\tthis.isPopping = false\n\n\t\t// Add delegated link events\n\t\tthis.attachEvents(links)\n\n\t\tthis.currentLocation = processUrl(window.location.href)\n\n\t\t// as this is the initial page load, prime this page into the cache\n\t\tthis.cache.set(this.currentLocation.href, this.createCacheEntry(document.cloneNode(true), window.location.href))\n\n\t\t// fire the current Renderer enter methods\n\t\tthis.currentCacheEntry = this.cache.get(this.currentLocation.href)\n\t\tthis.currentCacheEntry.renderer.initialLoad()\n\t}\n\n\t/**\n\t * @param {string} renderer\n\t */\n\tsetDefaultRenderer(renderer) {\n\t\tthis.defaultRenderer = this.renderers[renderer]\n\t}\n\n\t/**\n\t * @param {string} transition\n\t */\n\tsetDefaultTransition(transition) {\n\t\tthis.defaultTransition = this.transitions[transition]\n\t}\n\n\t/**\n\t * Registers a route into the RouteStore\n\t *\n\t * @param {string} fromPattern\n\t * @param {string} toPattern\n\t * @param {string} transition\n\t */\n\taddRoute(fromPattern, toPattern, transition) {\n\t\tif (!this.router) {\n\t\t\tthis.router = new RouteStore()\n\t\t}\n\n\t\tthis.router.add(fromPattern, toPattern, transition)\n\t}\n\n\t/**\n\t * Prime the cache for a given URL\n\t *\n\t * @param {string} url\n\t * @param {boolean} [preloadAssets]\n\t * @return {Promise}\n\t */\n\tpreload(url, preloadAssets = false) {\n\t\t// convert relative URLs to absolute\n\t\turl = processUrl(url).href\n\n\t\tif (!this.cache.has(url)) {\n\t\t\treturn this.fetch(url, false)\n\t\t\t\t.then(async (response) => {\n\t\t\t\t\tthis.cache.set(url, this.createCacheEntry(response.html, response.url))\n\n\t\t\t\t\tif (preloadAssets) {\n\t\t\t\t\t\tthis.cache.get(url).renderer.createDom()\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\t.catch(err => console.warn(err))\n\t\t}\n\n\t\treturn Promise.resolve()\n\t}\n\n\t/**\n\t * Updates the HTML cache for a given URL.\n\t * If no URL is passed, then cache for the current page is updated.\n\t * Useful when adding/removing content via AJAX such as a search page or infinite loader.\n\t *\n\t * @param {string} [url]\n\t */\n\tupdateCache(url) {\n\t\tconst key = processUrl(url || window.location.href).href\n\n\t\tif (this.cache.has(key)) {\n\t\t\tthis.cache.delete(key)\n\t\t}\n\n\t\tthis.cache.set(key, this.createCacheEntry(document.cloneNode(true), key))\n\t}\n\n\t/**\n\t * Clears the cache for a given URL.\n\t * If no URL is passed, then cache for the current page is cleared.\n\t *\n\t * @param {string} [url]\n\t */\n\tclearCache(url) {\n\t\tconst key = processUrl(url || window.location.href).href\n\n\t\tif (this.cache.has(key)) {\n\t\t\tthis.cache.delete(key)\n\t\t}\n\t}\n\n\t/**\n\t * @param {string} url\n\t * @param {string|false} [transition]\n\t * @param {string|false|HTMLElement} [trigger]\n\t * @return {Promise}\n\t */\n\tnavigateTo(url, transition = false, trigger = false) {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\t// Don't allow multiple navigations to occur at once\n\t\t\tif (!this.allowInterruption && this.isTransitioning) {\n\t\t\t\treject(new Error(IN_PROGRESS))\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tthis.isTransitioning = true\n\t\t\tthis.isPopping = true\n\t\t\tthis.targetLocation = processUrl(url)\n\t\t\tthis.popTarget = window.location.href\n\n\t\t\tconst TransitionClass = new (this.chooseTransition(transition))({ wrapper: this.wrapper })\n\n\t\t\tlet navigationPromise\n\n\t\t\tif (this.bypassCache || !this.cache.has(this.targetLocation.href) || this.cache.get(this.targetLocation.href).skipCache) {\n\t\t\t\tconst fetched = this.fetch(this.targetLocation.href)\n\t\t\t\t\t.then((response) => {\n\t\t\t\t\t\tthis.cache.set(this.targetLocation.href, this.createCacheEntry(response.html, response.url))\n\t\t\t\t\t\tthis.cache.get(this.targetLocation.href).renderer.createDom()\n\t\t\t\t\t})\n\t\t\t\t\t.catch(err => {\n\t\t\t\t\t\t// we encountered a 4** or 5** error, redirect to the requested URL\n\t\t\t\t\t\twindow.location.href = url\n\t\t\t\t\t})\n\n\t\t\t\tnavigationPromise = this.beforeFetch(this.targetLocation, TransitionClass, trigger)\n\t\t\t\t\t.then(async () => {\n\t\t\t\t\t\treturn fetched.then(async () => {\n\t\t\t\t\t\t\treturn await this.afterFetch(this.targetLocation, TransitionClass, this.cache.get(this.targetLocation.href), trigger)\n\t\t\t\t\t\t})\n\t\t\t\t\t})\n\t\t\t} else {\n\t\t\t\tthis.cache.get(this.targetLocation.href).renderer.createDom()\n\n\t\t\t\tnavigationPromise = this.beforeFetch(this.targetLocation, TransitionClass, trigger)\n\t\t\t\t\t.then(async () => {\n\t\t\t\t\t\treturn await this.afterFetch(this.targetLocation, TransitionClass, this.cache.get(this.targetLocation.href), trigger)\n\t\t\t\t\t})\n\t\t\t}\n\n\t\t\tnavigationPromise.then(() => {\n\t\t\t\tresolve()\n\t\t\t})\n\t\t})\n\t}\n\n\t/**\n\t * Add an event listener.\n\t * @param {string} event\n\t * @param {any} callback\n\t */\n\ton(event, callback) {\n\t\tE.on(event, callback)\n\t}\n\n\t/**\n\t * Remove an event listener.\n\t * @param {string} event\n\t * @param {any} [callback]\n\t */\n\toff(event, callback) {\n\t\tE.off(event, callback)\n\t}\n\n\t/**\n\t * @private\n\t * @param {{ raw: string, href: string, hasHash: boolean, pathname: string }} url\n\t * @param {Transition} TransitionClass\n\t * @param {string|HTMLElement|false} trigger\n\t * @return {Promise}\n\t */\n\tbeforeFetch(url, TransitionClass, trigger) {\n\t\tE.emit('NAVIGATE_OUT', {\n\t\t\tfrom: this.currentCacheEntry,\n\t\t\ttrigger\n\t\t})\n\n\t\treturn new Promise((resolve) => {\n\t\t\tthis.currentCacheEntry.renderer.leave(TransitionClass, trigger, this.removeOldContent)\n\t\t\t\t.then(() => {\n\t\t\t\t\tif (trigger !== 'popstate') {\n\t\t\t\t\t\twindow.history.pushState({}, '', url.raw)\n\t\t\t\t\t}\n\n\t\t\t\t\tresolve()\n\t\t\t\t})\n\t\t})\n\t}\n\n\t/**\n\t * @private\n\t * @param {{ raw: string, href: string, host: string, hasHash: boolean, pathname: string }} url\n\t * @param {Transition} TransitionClass\n\t * @param {CacheEntry} entry\n\t * @param {string|HTMLElement|false} trigger\n\t * @return {Promise}\n\t */\n\tafterFetch(url, TransitionClass, entry, trigger) {\n\t\tthis.currentLocation = url\n\t\tthis.popTarget = this.currentLocation.href\n\n\t\treturn new Promise((resolve) => {\n\t\t\tentry.renderer.update()\n\n\t\t\tE.emit('NAVIGATE_IN', {\n\t\t\t\tfrom: this.currentCacheEntry,\n\t\t\t\tto: entry,\n\t\t\t\ttrigger\n\t\t\t})\n\n\t\t\tif (this.reloadJsFilter) {\n\t\t\t\tthis.loadScripts(entry.scripts)\n\t\t\t}\n\n\t\t\tif (this.reloadCssFilter) {\n\t\t\t\tthis.loadStyles(entry.styles)\n\t\t\t}\n\n\t\t\t// If the fetched url had a redirect chain, then replace the history to reflect the final resolved URL\n\t\t\tif (trigger !== 'popstate' && url.href !== entry.finalUrl) {\n\t\t\t\twindow.history.replaceState({}, '', entry.finalUrl)\n\t\t\t}\n\n\t\t\tentry.renderer.enter(TransitionClass, trigger)\n\t\t\t\t.then(() => {\n\t\t\t\t\tE.emit('NAVIGATE_END', {\n\t\t\t\t\t\tfrom: this.currentCacheEntry,\n\t\t\t\t\t\tto: entry,\n\t\t\t\t\t\ttrigger\n\t\t\t\t\t})\n\n\t\t\t\t\tthis.currentCacheEntry = entry\n\t\t\t\t\tthis.isTransitioning = false\n\t\t\t\t\tthis.isPopping = false\n\t\t\t\t\tresolve()\n\t\t\t\t})\n\t\t})\n\t}\n\n\t/**\n\t * Load up scripts from the target page if needed\n\t *\n\t * @param {HTMLElement[]} cachedScripts\n\t */\n\tloadScripts(cachedScripts) {\n\t\tconst newScripts = [...cachedScripts]\n\t\tconst currentScripts = Array.from(document.querySelectorAll('script')).filter(this.reloadJsFilter)\n\n\t\t// loop through all new scripts\n\t\tfor (let i = 0; i < currentScripts.length; i++) {\n\t\t\tfor (let n = 0; n < newScripts.length; n++) {\n\t\t\t\tif (currentScripts[i].outerHTML === newScripts[n].outerHTML) {\n\t\t\t\t\treloadElement(currentScripts[i], 'SCRIPT')\n\t\t\t\t\tnewScripts.splice(n, 1)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tfor (const script of newScripts) {\n\t\t\tappendElement(script, 'SCRIPT')\n\t\t}\n\t}\n\n\t/**\n\t * Load up styles from the target page if needed\n\t *\n\t * @param {Array} cachedStyles\n\t */\n\tloadStyles(cachedStyles) {\n\t\tconst currentStyles = Array.from(document.querySelectorAll('link[rel=\"stylesheet\"]')).filter(this.reloadCssFilter)\n\t\tconst currentInlineStyles = Array.from(document.querySelectorAll('style')).filter(this.reloadCssFilter)\n\n\t\tconst newInlineStyles = cachedStyles.filter(el => {\n\t\t\t// no el.href, assume it's an inline style\n\t\t\tif (!el.href) {\n\t\t\t\treturn true\n\t\t\t} else if (!currentStyles.find((link) => link.href === el.href)) {\n\t\t\t\tdocument.body.append(el)\n\t\t\t\treturn false\n\t\t\t}\n\t\t})\n\n\t\t// loop through all new inline styles\n\t\tfor (let i = 0; i < currentInlineStyles.length; i++) {\n\t\t\tfor (let n = 0; n < newInlineStyles.length; n++) {\n\t\t\t\tif (currentInlineStyles[i].outerHTML === newInlineStyles[n].outerHTML) {\n\t\t\t\t\treloadElement(currentInlineStyles[i], 'STYLE')\n\t\t\t\t\tnewInlineStyles.splice(n, 1)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tfor (const style of newInlineStyles) {\n\t\t\tappendElement(style, 'STYLE')\n\t\t}\n\t}\n\n\t/**\n\t * @private\n\t * @param {string} links\n\t */\n\tattachEvents(links) {\n\t\tE.delegate('click', links, this.onClick)\n\t\tE.on('popstate', window, this.onPopstate)\n\n\t\tif (this.enablePrefetch) {\n\t\t\tE.delegate('mouseenter focus', links, this.onPrefetch)\n\t\t}\n\t}\n\n\t/**\n\t * @private\n\t * @param {MouseEvent} e\n\t */\n\tonClick = (e) => {\n\t\tif (!(e.metaKey || e.ctrlKey)) {\n\t\t\tconst target = processUrl(e.currentTarget.href)\n\t\t\tthis.currentLocation = processUrl(window.location.href)\n\n\t\t\tif (this.currentLocation.host !== target.host) {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// the target is a new URL, or is removing the hash from the current URL\n\t\t\tif (this.currentLocation.href !== target.href || (this.currentLocation.hasHash && !target.hasHash)) {\n\t\t\t\te.preventDefault()\n\t\t\t\t// noinspection JSIgnoredPromiseFromCall\n\t\t\t\tthis.navigateTo(target.raw, e.currentTarget.dataset.transition || false, e.currentTarget).catch(err => console.warn(err))\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// a click to the current URL was detected\n\t\t\tif (!this.currentLocation.hasHash && !target.hasHash) {\n\t\t\t\te.preventDefault()\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * @private\n\t * @return {void|boolean}\n\t */\n\tonPopstate = () => {\n\t\t// don't trigger for on-page anchors\n\t\tif (window.location.pathname === this.currentLocation.pathname && !this.isPopping) {\n\t\t\treturn false\n\t\t}\n\n\t\tif (!this.allowInterruption && (this.isTransitioning || this.isPopping)) {\n\t\t\t// overwrite history state with current page if currently navigating\n\t\t\twindow.history.pushState({}, '', this.popTarget)\n\t\t\tconsole.warn(IN_PROGRESS)\n\t\t\treturn false\n\t\t}\n\n\t\tif (!this.isPopping) {\n\t\t\tthis.popTarget = window.location.href\n\t\t}\n\n\t\tthis.isPopping = true\n\n\t\t// noinspection JSIgnoredPromiseFromCall\n\t\tthis.navigateTo(window.location.href, false, 'popstate')\n\t}\n\n\t/**\n\t * @private\n\t * @param {MouseEvent} e\n\t */\n\tonPrefetch = (e) => {\n\t\tconst target = processUrl(e.currentTarget.href)\n\n\t\tif (this.currentLocation.host !== target.host) {\n\t\t\treturn\n\t\t}\n\n\t\tthis.preload(e.currentTarget.href, false)\n\t}\n\n\t/**\n\t * @private\n\t * @param {string} url\n\t * @param {boolean} [runFallback]\n\t * @return {Promise<{html: Document, url: string}>}\n\t */\n\tfetch(url, runFallback = true) {\n\t\t// If Taxi is currently performing a fetch for the given URL, return that instead of starting a new request\n\t\tif (this.activePromises.has(url)) {\n\t\t\treturn this.activePromises.get(url)\n\t\t}\n\n\t\tconst request = new Promise((resolve, reject) => {\n\t\t\tlet resolvedUrl\n\n\t\t\tfetch(url, {\n\t\t\t\tmode: 'same-origin',\n\t\t\t\tmethod: 'GET',\n\t\t\t\theaders: { 'X-Requested-With': 'Taxi' },\n\t\t\t\tcredentials: 'same-origin'\n\t\t\t})\n\t\t\t\t.then((response) => {\n\t\t\t\t\tif (!response.ok) {\n\t\t\t\t\t\treject('Taxi encountered a non 2xx HTTP status code')\n\n\t\t\t\t\t\tif (runFallback) {\n\t\t\t\t\t\t\twindow.location.href = url\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tresolvedUrl = response.url\n\n\t\t\t\t\treturn response.text()\n\t\t\t\t})\n\t\t\t\t.then((htmlString) => {\n\t\t\t\t\tresolve({ html: parseDom(htmlString), url: resolvedUrl })\n\t\t\t\t})\n\t\t\t\t.catch((err) => {\n\t\t\t\t\treject(err)\n\n\t\t\t\t\tif (runFallback) {\n\t\t\t\t\t\twindow.location.href = url\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\t.finally(() => {\n\t\t\t\t\tthis.activePromises.delete(url)\n\t\t\t\t})\n\t\t})\n\n\t\tthis.activePromises.set(url, request)\n\n\t\treturn request\n\t}\n\n\t/**\n\t * @private\n\t * @param {string|false} transition\n\t * @return {Transition|function}\n\t */\n\tchooseTransition(transition) {\n\t\tif (transition) {\n\t\t\treturn this.transitions[transition]\n\t\t}\n\n\t\tconst routeTransition = this.router?.findMatch(this.currentLocation, this.targetLocation)\n\n\t\tif (routeTransition) {\n\t\t\treturn this.transitions[routeTransition]\n\t\t}\n\n\t\treturn this.defaultTransition\n\t}\n\n\t/**\n\t * @private\n\t * @param {Document|Node} page\n\t * @param {string} url\n\t * @return {CacheEntry}\n\t */\n\tcreateCacheEntry(page, url) {\n\t\tconst content = page.querySelector('[data-taxi-view]')\n\t\tconst Renderer = content.dataset.taxiView.length ? this.renderers[content.dataset.taxiView] : this.defaultRenderer\n\n\t\tif (!Renderer) {\n\t\t\tconsole.warn(`The Renderer \"${content.dataset.taxiView}\" was set in the data-taxi-view of the requested page, but not registered in Taxi.`)\n\t\t}\n\n\t\treturn {\n\t\t\tpage,\n\t\t\tcontent,\n\t\t\tfinalUrl: url,\n\t\t\tskipCache: content.hasAttribute('data-taxi-nocache'),\n\t\t\tscripts: this.reloadJsFilter ? Array.from(page.querySelectorAll('script')).filter(this.reloadJsFilter) : [],\n\t\t\tstyles: this.reloadCssFilter ? Array.from(page.querySelectorAll('link[rel=\"stylesheet\"], style')).filter(this.reloadCssFilter) : [],\n\t\t\ttitle: page.title,\n\t\t\trenderer: new Renderer({\n\t\t\t\twrapper: this.wrapper,\n\t\t\t\ttitle: page.title,\n\t\t\t\tcontent,\n\t\t\t\tpage\n\t\t\t})\n\t\t}\n\t}\n}\n"],"names":["parser","DOMParser","processUrl","url","details","URL","window","location","origin","normalized","hash","length","replace","hasHash","pathname","host","raw","href","reloadElement","node","elementType","parentNode","replaceChild","duplicateElement","appendElement","tagName","document","head","body","appendChild","replacement","createElement","k","attributes","attr","setAttribute","nodeName","nodeValue","innerHTML","Transition","this","wrapper","leave","props","Promise","resolve","_this","onLeave","done","enter","_this2","onEnter","Renderer","page","title","_contentString","content","outerHTML","_DOM","lastElementChild","onEnterCompleted","onLeaveCompleted","initialLoad","update","firstElementChild","createDom","remove","transition","trigger","to","then","removeOldContent","from","RouteStore","data","Map","regexCache","add","fromPattern","toPattern","has","set","RegExp","get","findMatch","currentUrl","nextUrl","potentialMatches","match","IN_PROGRESS","Core","parameters","isTransitioning","currentCacheEntry","cache","activePromises","onClick","e","metaKey","ctrlKey","target","currentTarget","currentLocation","preventDefault","navigateTo","dataset","err","console","warn","onPopstate","isPopping","allowInterruption","popTarget","history","pushState","onPrefetch","preload","links","bypassCache","enablePrefetch","renderers","transitions","default","reloadJsFilter","element","undefined","taxiReload","reloadCssFilter","defaultRenderer","defaultTransition","querySelector","attachEvents","createCacheEntry","cloneNode","renderer","setDefaultRenderer","setDefaultTransition","addRoute","router","preloadAssets","fetch","response","html","updateCache","key","clearCache","reject","_this3","targetLocation","navigationPromise","TransitionClass","chooseTransition","skipCache","fetched","beforeFetch","afterFetch","Error","on","event","callback","E","off","emit","_this4","entry","_this5","loadScripts","scripts","loadStyles","styles","finalUrl","replaceState","cachedScripts","newScripts","currentScripts","Array","querySelectorAll","filter","i","n","splice","cachedStyles","currentStyles","currentInlineStyles","newInlineStyles","el","find","link","append","delegate","runFallback","request","resolvedUrl","mode","method","headers","credentials","ok","text","htmlString","parseFromString","_this6","routeTransition","_this$router","taxiView","hasAttribute"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"taxi.umd.js","sources":["../src/helpers.js","../src/Transition.js","../src/Renderer.js","../src/RouteStore.js","../src/Core.js"],"sourcesContent":["const parser = new DOMParser()\n\n/**\n * Parse a HTML string into a proper Document.\n *\n * @param {string|Document} html\n * @return {Document|*}\n */\nexport function parseDom(html) {\n\treturn typeof html === 'string' ? parser.parseFromString(html, 'text/html') : html\n}\n\n/**\n * Extract details from a given URL string. Assumed to be on the current TLD.\n *\n * @param {string} url\n * @return {{raw: string, href: string, host: string, search: string, hasHash: boolean, pathname: string}}\n */\nexport function processUrl(url) {\n\tconst details = new URL(url, window.location.origin)\n\tconst normalized = details.hash.length ? url.replace(details.hash, '') : null\n\n\treturn {\n\t\thasHash: details.hash.length > 0,\n\t\tpathname: details.pathname,\n\t\thost: details.host,\n\t\tsearch: details.search,\n\t\traw: url,\n\t\thref: normalized || details.href\n\t}\n}\n\n/**\n * Reloads a provided script/stylesheet by replacing with itself.\n *\n * @param {HTMLElement|HTMLScriptElement|HTMLStyleElement} node\n * @param {string} elementType - 'SCRIPT' or 'STYLE'\n */\nexport function reloadElement(node, elementType) {\n\tnode.parentNode.replaceChild(duplicateElement(node, elementType), node)\n}\n\n/**\n * Loads a provided script/stylesheet by appending a clone to the current document.\n *\n * @param {HTMLElement|HTMLStyleElement} node\n * @param {string} elementType - 'SCRIPT' or 'STYLE'\n */\nexport function appendElement(node, elementType) {\n\tconst target = node.parentNode.tagName === 'HEAD' ? document.head : document.body\n\ttarget.appendChild(duplicateElement(node, elementType))\n}\n\n/**\n * Creates a clone of a given HTMLElement or HTMLStyleElement\n *\n * @param {HTMLElement|HTMLStyleElement} node\n * @param {string} elementType - 'SCRIPT' or 'STYLE'\n * @return {HTMLElement|HTMLStyleElement}\n */\nexport function duplicateElement(node, elementType) {\n\tconst replacement = document.createElement(elementType)\n\n\tfor (let k = 0; k < node.attributes.length; k++) {\n\t\tconst attr = node.attributes[k]\n\t\treplacement.setAttribute(attr.nodeName, attr.nodeValue)\n\t}\n\n\t// Inline Script or Style\n\tif (node.innerHTML) {\n\t\treplacement.innerHTML = node.innerHTML\n\t}\n\n\treturn replacement\n}\n","export default class Transition {\n\t/**\n\t * @param {{wrapper: HTMLElement}} props\n\t */\n\tconstructor({ wrapper }) {\n\t\tthis.wrapper = wrapper\n\t}\n\n\t/**\n\t * @param {{ from: HTMLElement|Element, trigger: string|HTMLElement|false }} props\n\t * @return {Promise}\n\t */\n\tleave(props) {\n\t\treturn new Promise((resolve) => {\n\t\t\tthis.onLeave({ ...props, done: resolve })\n\t\t})\n\t}\n\n\t/**\n\t * @param {{ to: HTMLElement|Element, trigger: string|HTMLElement|false }} props\n\t * @return {Promise}\n\t */\n\tenter(props) {\n\t\treturn new Promise((resolve) => {\n\t\t\tthis.onEnter({ ...props, done: resolve })\n\t\t})\n\t}\n\n\t/**\n\t * Handle the transition leaving the previous page.\n\t * @param {{from: HTMLElement|Element, trigger: string|HTMLElement|false, done: function}} props\n\t */\n\tonLeave({ from, trigger, done }) {\n\t\tdone()\n\t}\n\n\t/**\n\t * Handle the transition entering the next page.\n\t * @param {{to: HTMLElement|Element, trigger: string|HTMLElement|false, done: function}} props\n\t */\n\tonEnter({ to, trigger, done }) {\n\t\tdone()\n\t}\n}\n","import Transition from \"./Transition\"\n\nexport default class Renderer {\n\t/**\n\t * @param {{content: HTMLElement|Element, page: Document|Node, title: string, wrapper: Element}} props\n\t */\n\tconstructor({ content, page, title, wrapper }) {\n\t\tthis._contentString = content.outerHTML\n\t\tthis._DOM = null\n\t\tthis.page = page\n\t\tthis.title = title\n\t\tthis.wrapper = wrapper\n\t\tthis.content = this.wrapper.lastElementChild\n\t}\n\n\tonEnter() {\n\n\t}\n\n\tonEnterCompleted() {\n\n\t}\n\n\tonLeave() {\n\n\t}\n\n\tonLeaveCompleted() {\n\n\t}\n\n\tinitialLoad() {\n\t\tthis.onEnter()\n\t\tthis.onEnterCompleted()\n\t}\n\n\tupdate() {\n\t\tdocument.title = this.title\n\t\tthis.wrapper.appendChild(this._DOM.firstElementChild)\n\t\tthis.content = this.wrapper.lastElementChild\n\t\tthis._DOM = null\n\t}\n\n\tcreateDom() {\n\t\tif (!this._DOM) {\n\t\t\tthis._DOM = document.createElement('div')\n\t\t\tthis._DOM.innerHTML = this._contentString\n\t\t}\n\t}\n\n\tremove() {\n\t\tthis.wrapper.firstElementChild.remove()\n\t}\n\n\t/**\n\t * Called when transitioning into the current page.\n\t * @param {Transition} transition\n\t * @param {string|HTMLElement|false} trigger\n\t * @return {Promise}\n\t */\n\tenter(transition, trigger) {\n\t\treturn new Promise((resolve) => {\n\t\t\tthis.onEnter()\n\n\t\t\ttransition.enter({ trigger, to: this.content })\n\t\t\t\t.then(() => {\n\t\t\t\t\tthis.onEnterCompleted()\n\t\t\t\t\tresolve()\n\t\t\t\t})\n\t\t})\n\t}\n\n\t/**\n\t * Called when transitioning away from the current page.\n\t * @param {Transition} transition\n\t * @param {string|HTMLElement|false} trigger\n\t * @param {boolean} removeOldContent\n\t * @return {Promise}\n\t */\n\tleave(transition, trigger, removeOldContent) {\n\t\treturn new Promise((resolve) => {\n\t\t\tthis.onLeave()\n\n\t\t\ttransition.leave({ trigger, from: this.content })\n\t\t\t\t.then(() => {\n\t\t\t\t\tif (removeOldContent) {\n\t\t\t\t\t\tthis.remove()\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.onLeaveCompleted()\n\t\t\t\t\tresolve()\n\t\t\t\t})\n\t\t})\n\t}\n}\n","export default class RouteStore {\n\t/**\n\t * @type {Map>}\n\t */\n\tdata = new Map()\n\n\t/**\n\t * @type {Map}\n\t */\n\tregexCache = new Map()\n\n\t/**\n\t *\n\t * @param {string} fromPattern\n\t * @param {string} toPattern\n\t * @param {string} transition\n\t */\n\tadd(fromPattern, toPattern, transition) {\n\t\tif (!this.data.has(fromPattern)) {\n\t\t\tthis.data.set(fromPattern, new Map())\n\t\t\tthis.regexCache.set(fromPattern, new RegExp(`^${fromPattern}$`))\n\t\t}\n\n\t\tthis.data.get(fromPattern).set(toPattern, transition)\n\t\tthis.regexCache.set(toPattern, new RegExp(`^${toPattern}$`))\n\t}\n\n\t/**\n\t *\n\t * @param {{ raw: string, href: string, hasHash: boolean, pathname: string }} currentUrl\n\t * @param {{ raw: string, href: string, hasHash: boolean, pathname: string }} nextUrl\n\t * @return {string|null}\n\t */\n\tfindMatch(currentUrl, nextUrl) {\n\t\t// Loop through all from patterns\n\t\tfor (const [fromPattern, potentialMatches] of this.data) {\n\t\t\t// If we have a match\n\t\t\tif (currentUrl.pathname.match(this.regexCache.get(fromPattern))) {\n\t\t\t\t// loop through all associated to patterns\n\t\t\t\tfor (const [toPattern, transition] of potentialMatches) {\n\t\t\t\t\t// If we find a match, return it\n\t\t\t\t\tif (nextUrl.pathname.match(this.regexCache.get(toPattern))) {\n\t\t\t\t\t\treturn transition\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\treturn null\n\t}\n}\n","import E from '@unseenco/e'\nimport { appendElement, parseDom, processUrl, reloadElement } from './helpers'\nimport Transition from './Transition'\nimport Renderer from './Renderer'\nimport RouteStore from './RouteStore'\n\nconst IN_PROGRESS = 'A transition is currently in progress'\n\n/**\n * @typedef CacheEntry\n * @type {object}\n * @property {typeof Renderer|Renderer} renderer\n * @property {Document|Node} page\n * @property {array} scripts\n * @property {HTMLLinkElement[]} styles\n * @property {string} finalUrl\n * @property {boolean} skipCache\n * @property {string} title\n * @property {HTMLElement|Element} content\n */\n\nexport default class Core {\n\tisTransitioning = false\n\n\t/**\n\t * @type {CacheEntry|null}\n\t */\n\tcurrentCacheEntry = null\n\n\t/**\n\t * @type {Map}\n\t */\n\tcache = new Map()\n\n\t/**\n\t * @private\n\t * @type {Map}\n\t */\n\tactivePromises = new Map()\n\n\t/**\n\t * @param {{\n\t * \t\tlinks?: string,\n\t * \t\tremoveOldContent?: boolean,\n\t * \t\tallowInterruption?: boolean,\n\t * \t\tbypassCache?: boolean,\n\t * \t\tenablePrefetch?: boolean,\n\t * \t\trenderers?: Object.,\n\t * \t\ttransitions?: Object.,\n\t * \t\treloadJsFilter?: boolean|function(HTMLElement): boolean,\n\t * \t\treloadCssFilter?: boolean|function(HTMLLinkElement): boolean\n\t * }} parameters\n\t */\n\tconstructor(parameters = {}) {\n\t\tconst {\n\t\t\tlinks = 'a:not([target]):not([href^=\\\\#]):not([data-taxi-ignore])',\n\t\t\tremoveOldContent = true,\n\t\t\tallowInterruption = false,\n\t\t\tbypassCache = false,\n\t\t\tenablePrefetch = true,\n\t\t\trenderers = {\n\t\t\t\tdefault: Renderer\n\t\t\t},\n\t\t\ttransitions = {\n\t\t\t\tdefault: Transition\n\t\t\t},\n\t\t\treloadJsFilter = (element) => element.dataset.taxiReload !== undefined,\n\t\t\treloadCssFilter = (element) => true //element.dataset.taxiReload !== undefined\n\t\t} = parameters\n\n\t\tthis.renderers = renderers\n\t\tthis.transitions = transitions\n\t\tthis.defaultRenderer = this.renderers.default || Renderer\n\t\tthis.defaultTransition = this.transitions.default || Transition\n\t\tthis.wrapper = document.querySelector('[data-taxi]')\n\t\tthis.reloadJsFilter = reloadJsFilter\n\t\tthis.reloadCssFilter = reloadCssFilter\n\t\tthis.removeOldContent = removeOldContent\n\t\tthis.allowInterruption = allowInterruption\n\t\tthis.bypassCache = bypassCache\n\t\tthis.enablePrefetch = enablePrefetch\n\t\tthis.cache = new Map()\n\t\tthis.isPopping = false\n\n\t\t// Add delegated link events\n\t\tthis.attachEvents(links)\n\n\t\tthis.currentLocation = processUrl(window.location.href)\n\n\t\t// as this is the initial page load, prime this page into the cache\n\t\tthis.cache.set(this.currentLocation.href, this.createCacheEntry(document.cloneNode(true), window.location.href))\n\n\t\t// fire the current Renderer enter methods\n\t\tthis.currentCacheEntry = this.cache.get(this.currentLocation.href)\n\t\tthis.currentCacheEntry.renderer.initialLoad()\n\t}\n\n\t/**\n\t * @param {string} renderer\n\t */\n\tsetDefaultRenderer(renderer) {\n\t\tthis.defaultRenderer = this.renderers[renderer]\n\t}\n\n\t/**\n\t * @param {string} transition\n\t */\n\tsetDefaultTransition(transition) {\n\t\tthis.defaultTransition = this.transitions[transition]\n\t}\n\n\t/**\n\t * Registers a route into the RouteStore\n\t *\n\t * @param {string} fromPattern\n\t * @param {string} toPattern\n\t * @param {string} transition\n\t */\n\taddRoute(fromPattern, toPattern, transition) {\n\t\tif (!this.router) {\n\t\t\tthis.router = new RouteStore()\n\t\t}\n\n\t\tthis.router.add(fromPattern, toPattern, transition)\n\t}\n\n\t/**\n\t * Prime the cache for a given URL\n\t *\n\t * @param {string} url\n\t * @param {boolean} [preloadAssets]\n\t * @return {Promise}\n\t */\n\tpreload(url, preloadAssets = false) {\n\t\t// convert relative URLs to absolute\n\t\turl = processUrl(url).href\n\n\t\tif (!this.cache.has(url)) {\n\t\t\treturn this.fetch(url, false)\n\t\t\t\t.then(async (response) => {\n\t\t\t\t\tthis.cache.set(url, this.createCacheEntry(response.html, response.url))\n\n\t\t\t\t\tif (preloadAssets) {\n\t\t\t\t\t\tthis.cache.get(url).renderer.createDom()\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\t.catch(err => console.warn(err))\n\t\t}\n\n\t\treturn Promise.resolve()\n\t}\n\n\t/**\n\t * Updates the HTML cache for a given URL.\n\t * If no URL is passed, then cache for the current page is updated.\n\t * Useful when adding/removing content via AJAX such as a search page or infinite loader.\n\t *\n\t * @param {string} [url]\n\t */\n\tupdateCache(url) {\n\t\tconst key = processUrl(url || window.location.href).href\n\n\t\tif (this.cache.has(key)) {\n\t\t\tthis.cache.delete(key)\n\t\t}\n\n\t\tthis.cache.set(key, this.createCacheEntry(document.cloneNode(true), key))\n\t}\n\n\t/**\n\t * Clears the cache for a given URL.\n\t * If no URL is passed, then cache for the current page is cleared.\n\t *\n\t * @param {string} [url]\n\t */\n\tclearCache(url) {\n\t\tconst key = processUrl(url || window.location.href).href\n\n\t\tif (this.cache.has(key)) {\n\t\t\tthis.cache.delete(key)\n\t\t}\n\t}\n\n\t/**\n\t * @param {string} url\n\t * @param {string|false} [transition]\n\t * @param {string|false|HTMLElement} [trigger]\n\t * @return {Promise}\n\t */\n\tnavigateTo(url, transition = false, trigger = false) {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\t// Don't allow multiple navigations to occur at once\n\t\t\tif (!this.allowInterruption && this.isTransitioning) {\n\t\t\t\treject(new Error(IN_PROGRESS))\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tthis.isTransitioning = true\n\t\t\tthis.isPopping = true\n\t\t\tthis.targetLocation = processUrl(url)\n\t\t\tthis.popTarget = window.location.href\n\n\t\t\tconst TransitionClass = new (this.chooseTransition(transition))({ wrapper: this.wrapper })\n\n\t\t\tlet navigationPromise\n\n\t\t\tif (this.bypassCache || !this.cache.has(this.targetLocation.href) || this.cache.get(this.targetLocation.href).skipCache) {\n\t\t\t\tconst fetched = this.fetch(this.targetLocation.href)\n\t\t\t\t\t.then((response) => {\n\t\t\t\t\t\tthis.cache.set(this.targetLocation.href, this.createCacheEntry(response.html, response.url))\n\t\t\t\t\t\tthis.cache.get(this.targetLocation.href).renderer.createDom()\n\t\t\t\t\t})\n\t\t\t\t\t.catch(err => {\n\t\t\t\t\t\t// we encountered a 4** or 5** error, redirect to the requested URL\n\t\t\t\t\t\twindow.location.href = url\n\t\t\t\t\t})\n\n\t\t\t\tnavigationPromise = this.beforeFetch(this.targetLocation, TransitionClass, trigger)\n\t\t\t\t\t.then(async () => {\n\t\t\t\t\t\treturn fetched.then(async () => {\n\t\t\t\t\t\t\treturn await this.afterFetch(this.targetLocation, TransitionClass, this.cache.get(this.targetLocation.href), trigger)\n\t\t\t\t\t\t})\n\t\t\t\t\t})\n\t\t\t} else {\n\t\t\t\tthis.cache.get(this.targetLocation.href).renderer.createDom()\n\n\t\t\t\tnavigationPromise = this.beforeFetch(this.targetLocation, TransitionClass, trigger)\n\t\t\t\t\t.then(async () => {\n\t\t\t\t\t\treturn await this.afterFetch(this.targetLocation, TransitionClass, this.cache.get(this.targetLocation.href), trigger)\n\t\t\t\t\t})\n\t\t\t}\n\n\t\t\tnavigationPromise.then(() => {\n\t\t\t\tresolve()\n\t\t\t})\n\t\t})\n\t}\n\n\t/**\n\t * Add an event listener.\n\t * @param {string} event\n\t * @param {any} callback\n\t */\n\ton(event, callback) {\n\t\tE.on(event, callback)\n\t}\n\n\t/**\n\t * Remove an event listener.\n\t * @param {string} event\n\t * @param {any} [callback]\n\t */\n\toff(event, callback) {\n\t\tE.off(event, callback)\n\t}\n\n\t/**\n\t * @private\n\t * @param {{ raw: string, href: string, hasHash: boolean, pathname: string }} url\n\t * @param {Transition} TransitionClass\n\t * @param {string|HTMLElement|false} trigger\n\t * @return {Promise}\n\t */\n\tbeforeFetch(url, TransitionClass, trigger) {\n\t\tE.emit('NAVIGATE_OUT', {\n\t\t\tfrom: this.currentCacheEntry,\n\t\t\ttrigger\n\t\t})\n\n\t\treturn new Promise((resolve) => {\n\t\t\tthis.currentCacheEntry.renderer.leave(TransitionClass, trigger, this.removeOldContent)\n\t\t\t\t.then(() => {\n\t\t\t\t\tif (trigger !== 'popstate') {\n\t\t\t\t\t\twindow.history.pushState({}, '', url.raw)\n\t\t\t\t\t}\n\n\t\t\t\t\tresolve()\n\t\t\t\t})\n\t\t})\n\t}\n\n\t/**\n\t * @private\n\t * @param {{ raw: string, href: string, host: string, hasHash: boolean, pathname: string }} url\n\t * @param {Transition} TransitionClass\n\t * @param {CacheEntry} entry\n\t * @param {string|HTMLElement|false} trigger\n\t * @return {Promise}\n\t */\n\tafterFetch(url, TransitionClass, entry, trigger) {\n\t\tthis.currentLocation = url\n\t\tthis.popTarget = this.currentLocation.href\n\n\t\treturn new Promise((resolve) => {\n\t\t\tentry.renderer.update()\n\n\t\t\tE.emit('NAVIGATE_IN', {\n\t\t\t\tfrom: this.currentCacheEntry,\n\t\t\t\tto: entry,\n\t\t\t\ttrigger\n\t\t\t})\n\n\t\t\tif (this.reloadJsFilter) {\n\t\t\t\tthis.loadScripts(entry.scripts)\n\t\t\t}\n\n\t\t\tif (this.reloadCssFilter) {\n\t\t\t\tthis.loadStyles(entry.styles)\n\t\t\t}\n\n\t\t\t// If the fetched url had a redirect chain, then replace the history to reflect the final resolved URL\n\t\t\tif (trigger !== 'popstate' && url.href !== entry.finalUrl) {\n\t\t\t\twindow.history.replaceState({}, '', entry.finalUrl)\n\t\t\t}\n\n\t\t\tentry.renderer.enter(TransitionClass, trigger)\n\t\t\t\t.then(() => {\n\t\t\t\t\tE.emit('NAVIGATE_END', {\n\t\t\t\t\t\tfrom: this.currentCacheEntry,\n\t\t\t\t\t\tto: entry,\n\t\t\t\t\t\ttrigger\n\t\t\t\t\t})\n\n\t\t\t\t\tthis.currentCacheEntry = entry\n\t\t\t\t\tthis.isTransitioning = false\n\t\t\t\t\tthis.isPopping = false\n\t\t\t\t\tresolve()\n\t\t\t\t})\n\t\t})\n\t}\n\n\t/**\n\t * Load up scripts from the target page if needed\n\t *\n\t * @param {HTMLElement[]} cachedScripts\n\t */\n\tloadScripts(cachedScripts) {\n\t\tconst newScripts = [...cachedScripts]\n\t\tconst currentScripts = Array.from(document.querySelectorAll('script')).filter(this.reloadJsFilter)\n\n\t\t// loop through all new scripts\n\t\tfor (let i = 0; i < currentScripts.length; i++) {\n\t\t\tfor (let n = 0; n < newScripts.length; n++) {\n\t\t\t\tif (currentScripts[i].outerHTML === newScripts[n].outerHTML) {\n\t\t\t\t\treloadElement(currentScripts[i], 'SCRIPT')\n\t\t\t\t\tnewScripts.splice(n, 1)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tfor (const script of newScripts) {\n\t\t\tappendElement(script, 'SCRIPT')\n\t\t}\n\t}\n\n\t/**\n\t * Load up styles from the target page if needed\n\t *\n\t * @param {Array} cachedStyles\n\t */\n\tloadStyles(cachedStyles) {\n\t\tconst currentStyles = Array.from(document.querySelectorAll('link[rel=\"stylesheet\"]')).filter(this.reloadCssFilter)\n\t\tconst currentInlineStyles = Array.from(document.querySelectorAll('style')).filter(this.reloadCssFilter)\n\n\t\tconst newInlineStyles = cachedStyles.filter(el => {\n\t\t\t// no el.href, assume it's an inline style\n\t\t\tif (!el.href) {\n\t\t\t\treturn true\n\t\t\t} else if (!currentStyles.find((link) => link.href === el.href)) {\n\t\t\t\tdocument.body.append(el)\n\t\t\t\treturn false\n\t\t\t}\n\t\t})\n\n\t\t// loop through all new inline styles\n\t\tfor (let i = 0; i < currentInlineStyles.length; i++) {\n\t\t\tfor (let n = 0; n < newInlineStyles.length; n++) {\n\t\t\t\tif (currentInlineStyles[i].outerHTML === newInlineStyles[n].outerHTML) {\n\t\t\t\t\treloadElement(currentInlineStyles[i], 'STYLE')\n\t\t\t\t\tnewInlineStyles.splice(n, 1)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tfor (const style of newInlineStyles) {\n\t\t\tappendElement(style, 'STYLE')\n\t\t}\n\t}\n\n\t/**\n\t * @private\n\t * @param {string} links\n\t */\n\tattachEvents(links) {\n\t\tE.delegate('click', links, this.onClick)\n\t\tE.on('popstate', window, this.onPopstate)\n\n\t\tif (this.enablePrefetch) {\n\t\t\tE.delegate('mouseenter focus', links, this.onPrefetch)\n\t\t}\n\t}\n\n\t/**\n\t * @private\n\t * @param {MouseEvent} e\n\t */\n\tonClick = (e) => {\n\t\tif (!(e.metaKey || e.ctrlKey)) {\n\t\t\tconst target = processUrl(e.currentTarget.href)\n\t\t\tthis.currentLocation = processUrl(window.location.href)\n\n\t\t\tif (this.currentLocation.host !== target.host) {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// the target is a new URL, or is removing the hash from the current URL\n\t\t\tif (this.currentLocation.href !== target.href || (this.currentLocation.hasHash && !target.hasHash)) {\n\t\t\t\te.preventDefault()\n\t\t\t\t// noinspection JSIgnoredPromiseFromCall\n\t\t\t\tthis.navigateTo(target.raw, e.currentTarget.dataset.transition || false, e.currentTarget).catch(err => console.warn(err))\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// a click to the current URL was detected\n\t\t\tif (!this.currentLocation.hasHash && !target.hasHash) {\n\t\t\t\te.preventDefault()\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * @private\n\t * @return {void|boolean}\n\t */\n\tonPopstate = () => {\n\t\t// don't trigger for on-page anchors\n\t\tif (\n\t\t\twindow.location.pathname === this.currentLocation.pathname\n\t\t\t&& window.location.search === this.currentLocation.search\n\t\t\t&& !this.isPopping\n\t\t) {\n\t\t\treturn false\n\t\t}\n\n\t\tif (!this.allowInterruption && (this.isTransitioning || this.isPopping)) {\n\t\t\t// overwrite history state with current page if currently navigating\n\t\t\twindow.history.pushState({}, '', this.popTarget)\n\t\t\tconsole.warn(IN_PROGRESS)\n\t\t\treturn false\n\t\t}\n\n\t\tif (!this.isPopping) {\n\t\t\tthis.popTarget = window.location.href\n\t\t}\n\n\t\tthis.isPopping = true\n\n\t\t// noinspection JSIgnoredPromiseFromCall\n\t\tthis.navigateTo(window.location.href, false, 'popstate')\n\t}\n\n\t/**\n\t * @private\n\t * @param {MouseEvent} e\n\t */\n\tonPrefetch = (e) => {\n\t\tconst target = processUrl(e.currentTarget.href)\n\n\t\tif (this.currentLocation.host !== target.host) {\n\t\t\treturn\n\t\t}\n\n\t\tthis.preload(e.currentTarget.href, false)\n\t}\n\n\t/**\n\t * @private\n\t * @param {string} url\n\t * @param {boolean} [runFallback]\n\t * @return {Promise<{html: Document, url: string}>}\n\t */\n\tfetch(url, runFallback = true) {\n\t\t// If Taxi is currently performing a fetch for the given URL, return that instead of starting a new request\n\t\tif (this.activePromises.has(url)) {\n\t\t\treturn this.activePromises.get(url)\n\t\t}\n\n\t\tconst request = new Promise((resolve, reject) => {\n\t\t\tlet resolvedUrl\n\n\t\t\tfetch(url, {\n\t\t\t\tmode: 'same-origin',\n\t\t\t\tmethod: 'GET',\n\t\t\t\theaders: { 'X-Requested-With': 'Taxi' },\n\t\t\t\tcredentials: 'same-origin'\n\t\t\t})\n\t\t\t\t.then((response) => {\n\t\t\t\t\tif (!response.ok) {\n\t\t\t\t\t\treject('Taxi encountered a non 2xx HTTP status code')\n\n\t\t\t\t\t\tif (runFallback) {\n\t\t\t\t\t\t\twindow.location.href = url\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tresolvedUrl = response.url\n\n\t\t\t\t\treturn response.text()\n\t\t\t\t})\n\t\t\t\t.then((htmlString) => {\n\t\t\t\t\tresolve({ html: parseDom(htmlString), url: resolvedUrl })\n\t\t\t\t})\n\t\t\t\t.catch((err) => {\n\t\t\t\t\treject(err)\n\n\t\t\t\t\tif (runFallback) {\n\t\t\t\t\t\twindow.location.href = url\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\t.finally(() => {\n\t\t\t\t\tthis.activePromises.delete(url)\n\t\t\t\t})\n\t\t})\n\n\t\tthis.activePromises.set(url, request)\n\n\t\treturn request\n\t}\n\n\t/**\n\t * @private\n\t * @param {string|false} transition\n\t * @return {Transition|function}\n\t */\n\tchooseTransition(transition) {\n\t\tif (transition) {\n\t\t\treturn this.transitions[transition]\n\t\t}\n\n\t\tconst routeTransition = this.router?.findMatch(this.currentLocation, this.targetLocation)\n\n\t\tif (routeTransition) {\n\t\t\treturn this.transitions[routeTransition]\n\t\t}\n\n\t\treturn this.defaultTransition\n\t}\n\n\t/**\n\t * @private\n\t * @param {Document|Node} page\n\t * @param {string} url\n\t * @return {CacheEntry}\n\t */\n\tcreateCacheEntry(page, url) {\n\t\tconst content = page.querySelector('[data-taxi-view]')\n\t\tconst Renderer = content.dataset.taxiView.length ? this.renderers[content.dataset.taxiView] : this.defaultRenderer\n\n\t\tif (!Renderer) {\n\t\t\tconsole.warn(`The Renderer \"${content.dataset.taxiView}\" was set in the data-taxi-view of the requested page, but not registered in Taxi.`)\n\t\t}\n\n\t\treturn {\n\t\t\tpage,\n\t\t\tcontent,\n\t\t\tfinalUrl: url,\n\t\t\tskipCache: content.hasAttribute('data-taxi-nocache'),\n\t\t\tscripts: this.reloadJsFilter ? Array.from(page.querySelectorAll('script')).filter(this.reloadJsFilter) : [],\n\t\t\tstyles: this.reloadCssFilter ? Array.from(page.querySelectorAll('link[rel=\"stylesheet\"], style')).filter(this.reloadCssFilter) : [],\n\t\t\ttitle: page.title,\n\t\t\trenderer: new Renderer({\n\t\t\t\twrapper: this.wrapper,\n\t\t\t\ttitle: page.title,\n\t\t\t\tcontent,\n\t\t\t\tpage\n\t\t\t})\n\t\t}\n\t}\n}\n"],"names":["parser","DOMParser","processUrl","url","details","URL","window","location","origin","normalized","hash","length","replace","hasHash","pathname","host","search","raw","href","reloadElement","node","elementType","parentNode","replaceChild","duplicateElement","appendElement","tagName","document","head","body","appendChild","replacement","createElement","k","attributes","attr","setAttribute","nodeName","nodeValue","innerHTML","Transition","this","wrapper","leave","props","Promise","resolve","_this","onLeave","done","enter","_this2","onEnter","Renderer","page","title","_contentString","content","outerHTML","_DOM","lastElementChild","onEnterCompleted","onLeaveCompleted","initialLoad","update","firstElementChild","createDom","remove","transition","trigger","to","then","removeOldContent","from","RouteStore","data","Map","regexCache","add","fromPattern","toPattern","has","set","RegExp","get","findMatch","currentUrl","nextUrl","potentialMatches","match","IN_PROGRESS","Core","parameters","isTransitioning","currentCacheEntry","cache","activePromises","onClick","e","metaKey","ctrlKey","target","currentTarget","currentLocation","preventDefault","navigateTo","dataset","err","console","warn","onPopstate","isPopping","allowInterruption","popTarget","history","pushState","onPrefetch","preload","links","bypassCache","enablePrefetch","renderers","transitions","default","reloadJsFilter","element","undefined","taxiReload","reloadCssFilter","defaultRenderer","defaultTransition","querySelector","attachEvents","createCacheEntry","cloneNode","renderer","setDefaultRenderer","setDefaultTransition","addRoute","router","preloadAssets","fetch","response","html","updateCache","key","clearCache","reject","_this3","targetLocation","navigationPromise","TransitionClass","chooseTransition","skipCache","fetched","beforeFetch","afterFetch","Error","on","event","callback","E","off","emit","_this4","entry","_this5","loadScripts","scripts","loadStyles","styles","finalUrl","replaceState","cachedScripts","newScripts","currentScripts","Array","querySelectorAll","filter","i","n","splice","cachedStyles","currentStyles","currentInlineStyles","newInlineStyles","el","find","link","append","delegate","runFallback","request","resolvedUrl","mode","method","headers","credentials","ok","text","htmlString","parseFromString","_this6","routeTransition","_this$router","taxiView","hasAttribute"],"mappings":"+2CAAA,IAAMA,EAAS,IAAIC,mBAkBHC,EAAWC,GAC1B,IAAMC,EAAU,IAAIC,IAAIF,EAAKG,OAAOC,SAASC,QACvCC,EAAaL,EAAQM,KAAKC,OAASR,EAAIS,QAAQR,EAAQM,KAAM,IAAM,KAEzE,MAAO,CACNG,QAAST,EAAQM,KAAKC,OAAS,EAC/BG,SAAUV,EAAQU,SAClBC,KAAMX,EAAQW,KACdC,OAAQZ,EAAQY,OAChBC,IAAKd,EACLe,KAAMT,GAAcL,EAAQc,KAE7B,UAQeC,EAAcC,EAAMC,GACnCD,EAAKE,WAAWC,aAAaC,EAAiBJ,EAAMC,GAAcD,EAClE,UAQeK,EAAcL,EAAMC,IACQ,SAA5BD,EAAKE,WAAWI,QAAqBC,SAASC,KAAOD,SAASE,MACtEC,YAAYN,EAAiBJ,EAAMC,GAC1C,UASeG,EAAiBJ,EAAMC,GAGtC,IAFA,IAAMU,EAAcJ,SAASK,cAAcX,GAElCY,EAAI,EAAGA,EAAIb,EAAKc,WAAWvB,OAAQsB,IAAK,CAChD,IAAME,EAAOf,EAAKc,WAAWD,GAC7BF,EAAYK,aAAaD,EAAKE,SAAUF,EAAKG,UAC7C,CAOD,OAJIlB,EAAKmB,YACRR,EAAYQ,UAAYnB,EAAKmB,WAGvBR,CACP,KC1EoBS,0BAIpB,cACCC,KAAKC,UADQA,OAEb,4BAMDC,MAAA,SAAMC,cACL,WAAWC,QAAQ,SAACC,GACnBC,EAAKC,aAAaJ,GAAOK,KAAMH,IAC/B,EACD,IAMDI,MAAA,SAAMN,cACL,WAAWC,QAAQ,SAACC,GACnBK,EAAKC,aAAaR,GAAOK,KAAMH,IAC/B,EACD,IAMDE,QAAA,aACCC,IADwBA,OAExB,IAMDG,QAAA,aACCH,IADsBA,OAEtB,OCxCmBI,0BAIpB,kBAAuBC,IAAAA,KAAMC,IAAAA,MAAOb,IAAAA,QACnCD,KAAKe,iBADQC,QACiBC,UAC9BjB,KAAKkB,KAAO,KACZlB,KAAKa,KAAOA,EACZb,KAAKc,MAAQA,EACbd,KAAKC,QAAUA,EACfD,KAAKgB,QAAUhB,KAAKC,QAAQkB,gBAC5B,4BAEDR,QAAA,eAIAS,iBAAA,eAIAb,QAAA,eAIAc,iBAAA,eAIAC,YAAA,WACCtB,KAAKW,UACLX,KAAKoB,kBACL,IAEDG,OAAA,WACCrC,SAAS4B,MAAQd,KAAKc,MACtBd,KAAKC,QAAQZ,YAAYW,KAAKkB,KAAKM,mBACnCxB,KAAKgB,QAAUhB,KAAKC,QAAQkB,iBAC5BnB,KAAKkB,KAAO,IACZ,IAEDO,UAAA,WACMzB,KAAKkB,OACTlB,KAAKkB,KAAOhC,SAASK,cAAc,OACnCS,KAAKkB,KAAKpB,UAAYE,KAAKe,eAE5B,IAEDW,OAAA,WACC1B,KAAKC,QAAQuB,kBAAkBE,QAC/B,IAQDjB,MAAA,SAAMkB,EAAYC,cACjB,WAAWxB,QAAQ,SAACC,GACnBC,EAAKK,UAELgB,EAAWlB,MAAM,CAAEmB,QAAAA,EAASC,GAAIvB,EAAKU,UACnCc,KAAK,WACLxB,EAAKc,mBACLf,GACA,EACF,EACD,IASDH,MAAA,SAAMyB,EAAYC,EAASG,cAC1B,WAAW3B,QAAQ,SAACC,GACnBK,EAAKH,UAELoB,EAAWzB,MAAM,CAAE0B,QAAAA,EAASI,KAAMtB,EAAKM,UACrCc,KAAK,WACDC,GACHrB,EAAKgB,SAGNhB,EAAKW,mBACLhB,GACA,EACF,EACD,OC7FmB4B,4CAIpBC,KAAO,IAAIC,SAKXC,WAAa,IAAID,+BAQjBE,IAAA,SAAIC,EAAaC,EAAWZ,GACtB3B,KAAKkC,KAAKM,IAAIF,KAClBtC,KAAKkC,KAAKO,IAAIH,EAAa,IAAIH,KAC/BnC,KAAKoC,WAAWK,IAAIH,EAAa,IAAII,WAAWJ,SAGjDtC,KAAKkC,KAAKS,IAAIL,GAAaG,IAAIF,EAAWZ,GAC1C3B,KAAKoC,WAAWK,IAAIF,EAAW,IAAIG,WAAWH,OAC9C,IAQDK,UAAA,SAAUC,EAAYC,GAErB,cAA8C9C,KAAKkC,qBAAM,eAAhCa,OAExB,GAAIF,EAAWxE,SAAS2E,MAAMhD,KAAKoC,WAAWO,WAAmB,CAEhE,cAAsCI,kBAAkB,eAAjCpB,OAEtB,GAAImB,EAAQzE,SAAS2E,MAAMhD,KAAKoC,WAAWO,WAC1C,OAAOhB,CAER,CAED,KACA,CACD,CAED,WACA,OC7CIsB,EAAc,wCAeCC,0BAgCpB,WAAYC,uBAAAA,IAAAA,EAAa,SA/BzBC,iBAAkB,OAKlBC,kBAAoB,UAKpBC,MAAQ,IAAInB,SAMZoB,eAAiB,IAAIpB,SAkXrBqB,QAAU,SAACC,GACV,IAAMA,EAAEC,UAAWD,EAAEE,QAAU,CAC9B,IAAMC,EAASnG,EAAWgG,EAAEI,cAAcpF,MAG1C,GAFA6B,EAAKwD,gBAAkBrG,EAAWI,OAAOC,SAASW,MAE9C6B,EAAKwD,gBAAgBxF,OAASsF,EAAOtF,KACxC,OAID,GAAIgC,EAAKwD,gBAAgBrF,OAASmF,EAAOnF,MAAS6B,EAAKwD,gBAAgB1F,UAAYwF,EAAOxF,QAIzF,OAHAqF,EAAEM,sBAEFzD,EAAK0D,WAAWJ,EAAOpF,IAAKiF,EAAEI,cAAcI,QAAQtC,aAAc,EAAO8B,EAAEI,qBAAqB,SAAAK,UAAOC,QAAQC,KAAKF,EAAjB,GAK/F5D,EAAKwD,gBAAgB1F,SAAYwF,EAAOxF,SAC5CqF,EAAEM,gBAEH,CACD,OAMDM,WAAa,WAEZ,QACCxG,OAAOC,SAASO,WAAaiC,EAAKwD,gBAAgBzF,UAC/CR,OAAOC,SAASS,SAAW+B,EAAKwD,gBAAgBvF,SAC/C+B,EAAKgE,aAKLhE,EAAKiE,oBAAsBjE,EAAK8C,kBAAmB9C,EAAKgE,WAOxDhE,EAAKgE,YACThE,EAAKkE,UAAY3G,OAAOC,SAASW,MAGlC6B,EAAKgE,WAAY,OAGjBhE,EAAK0D,WAAWnG,OAAOC,SAASW,MAAM,EAAO,cAZ5CZ,OAAO4G,QAAQC,UAAU,GAAI,GAAIpE,EAAKkE,WACtCL,QAAQC,KAAKnB,OAYd,OAMD0B,WAAa,SAAClB,GACb,IAAMG,EAASnG,EAAWgG,EAAEI,cAAcpF,MAEtC6B,EAAKwD,gBAAgBxF,OAASsF,EAAOtF,MAIzCgC,EAAKsE,QAAQnB,EAAEI,cAAcpF,MAAM,EACnC,EAraA,MAcI0E,EAbH0B,MAAAA,aAAQ,+DAaL1B,EAZHpB,iBAAAA,kBAYGoB,EAXHoB,kBAAAA,kBAWGpB,EAVH2B,YAAAA,kBAUG3B,EATH4B,eAAAA,kBASG5B,EARH6B,YAQG7B,EALH8B,YAAAA,aAAc,CACbC,QAASnF,OAIPoD,EAFHgC,eAAAA,aAAiB,SAACC,eAA2CC,IAA/BD,EAAQnB,QAAQqB,UAA7B,MAEdnC,EADHoC,gBAAAA,aAAkB,SAACH,WAAD,IAGnBpF,KAAKgF,qBAVQ,CACXE,QAAStE,KAUXZ,KAAKiF,YAAcA,EACnBjF,KAAKwF,gBAAkBxF,KAAKgF,mBAAqBpE,EACjDZ,KAAKyF,kBAAoBzF,KAAKiF,qBAAuBlF,EACrDC,KAAKC,QAAUf,SAASwG,cAAc,eACtC1F,KAAKmF,eAAiBA,EACtBnF,KAAKuF,gBAAkBA,EACvBvF,KAAK+B,iBAAmBA,EACxB/B,KAAKuE,kBAAoBA,EACzBvE,KAAK8E,YAAcA,EACnB9E,KAAK+E,eAAiBA,EACtB/E,KAAKsD,MAAQ,IAAInB,IACjBnC,KAAKsE,WAAY,EAGjBtE,KAAK2F,aAAad,GAElB7E,KAAK8D,gBAAkBrG,EAAWI,OAAOC,SAASW,MAGlDuB,KAAKsD,MAAMb,IAAIzC,KAAK8D,gBAAgBrF,KAAMuB,KAAK4F,iBAAiB1G,SAAS2G,WAAU,GAAOhI,OAAOC,SAASW,OAG1GuB,KAAKqD,kBAAoBrD,KAAKsD,MAAMX,IAAI3C,KAAK8D,gBAAgBrF,MAC7DuB,KAAKqD,kBAAkByC,SAASxE,aAChC,4BAKDyE,mBAAA,SAAmBD,GAClB9F,KAAKwF,gBAAkBxF,KAAKgF,UAAUc,EACtC,IAKDE,qBAAA,SAAqBrE,GACpB3B,KAAKyF,kBAAoBzF,KAAKiF,YAAYtD,EAC1C,IASDsE,SAAA,SAAS3D,EAAaC,EAAWZ,GAC3B3B,KAAKkG,SACTlG,KAAKkG,OAAS,IAAIjE,GAGnBjC,KAAKkG,OAAO7D,IAAIC,EAAaC,EAAWZ,EACxC,IASDiD,QAAA,SAAQlH,EAAKyI,SAOTnG,KAHH,gBAJYmG,IAAAA,GAAgB,GAE5BzI,EAAMD,EAAWC,GAAKe,KAEjBuB,KAAKsD,MAAMd,IAAI9E,GAYb0C,QAAQC,eAXF+F,MAAM1I,GAAK,GACrBoE,cAAYuE,OAAa,OACzB3F,EAAK4C,MAAMb,IAAI/E,EAAKgD,EAAKkF,iBAAiBS,EAASC,KAAMD,EAAS3I,MAE9DyI,GACHzF,EAAK4C,MAAMX,IAAIjF,GAAKoI,SAASrE,8BALzB,2CAQC,SAAAyC,UAAOC,QAAQC,KAAKF,EAAjB,EAIZ,IASDqC,YAAA,SAAY7I,GACX,IAAM8I,EAAM/I,EAAWC,GAAOG,OAAOC,SAASW,MAAMA,KAEhDuB,KAAKsD,MAAMd,IAAIgE,IAClBxG,KAAKsD,aAAakD,GAGnBxG,KAAKsD,MAAMb,IAAI+D,EAAKxG,KAAK4F,iBAAiB1G,SAAS2G,WAAU,GAAOW,GACpE,IAQDC,WAAA,SAAW/I,GACV,IAAM8I,EAAM/I,EAAWC,GAAOG,OAAOC,SAASW,MAAMA,KAEhDuB,KAAKsD,MAAMd,IAAIgE,IAClBxG,KAAKsD,aAAakD,EAEnB,IAQDxC,WAAA,SAAWtG,EAAKiE,EAAoBC,cACnC,gBADeD,IAAAA,GAAa,YAAOC,IAAAA,GAAU,OAClCxB,QAAQ,SAACC,EAASqG,GAE5B,GAAKC,EAAKpC,oBAAqBoC,EAAKvD,gBAApC,CAKAuD,EAAKvD,iBAAkB,EACvBuD,EAAKrC,WAAY,EACjBqC,EAAKC,eAAiBnJ,EAAWC,GACjCiJ,EAAKnC,UAAY3G,OAAOC,SAASW,KAEjC,IAEIoI,EAFEC,EAAkB,IAAKH,EAAKI,iBAAiBpF,GAA3B,CAAwC,CAAE1B,QAAS0G,EAAK1G,UAIhF,GAAI0G,EAAK7B,cAAgB6B,EAAKrD,MAAMd,IAAImE,EAAKC,eAAenI,OAASkI,EAAKrD,MAAMX,IAAIgE,EAAKC,eAAenI,MAAMuI,UAAW,CACxH,IAAMC,EAAUN,EAAKP,MAAMO,EAAKC,eAAenI,MAC7CqD,KAAK,SAACuE,GACNM,EAAKrD,MAAMb,IAAIkE,EAAKC,eAAenI,KAAMkI,EAAKf,iBAAiBS,EAASC,KAAMD,EAAS3I,MACvFiJ,EAAKrD,MAAMX,IAAIgE,EAAKC,eAAenI,MAAMqH,SAASrE,WAClD,SACM,SAAAyC,GAENrG,OAAOC,SAASW,KAAOf,CACvB,GAEFmJ,EAAoBF,EAAKO,YAAYP,EAAKC,eAAgBE,EAAiBlF,GACzEE,oBACA,uBAAOmF,EAAQnF,2CACD6E,EAAKQ,WAAWR,EAAKC,eAAgBE,EAAiBH,EAAKrD,MAAMX,IAAIgE,EAAKC,eAAenI,MAAOmD,IADvG,sCAFW,oCAMpB,MACA+E,EAAKrD,MAAMX,IAAIgE,EAAKC,eAAenI,MAAMqH,SAASrE,YAElDoF,EAAoBF,EAAKO,YAAYP,EAAKC,eAAgBE,EAAiBlF,GACzEE,2CACa6E,EAAKQ,WAAWR,EAAKC,eAAgBE,EAAiBH,EAAKrD,MAAMX,IAAIgE,EAAKC,eAAenI,MAAOmD,IAF3F,qCAMrBiF,EAAkB/E,KAAK,WACtBzB,GACA,EAvCA,MAFAqG,EAAO,IAAIU,MAAMnE,GA0ClB,EACD,IAODoE,GAAA,SAAGC,EAAOC,GACTC,UAAEH,GAAGC,EAAOC,EACZ,IAODE,IAAA,SAAIH,EAAOC,GACVC,UAAEC,IAAIH,EAAOC,EACb,IASDL,YAAA,SAAYxJ,EAAKoJ,EAAiBlF,cAMjC,OALA4F,UAAEE,KAAK,eAAgB,CACtB1F,KAAMhC,KAAKqD,kBACXzB,QAAAA,QAGUxB,QAAQ,SAACC,GACnBsH,EAAKtE,kBAAkByC,SAAS5F,MAAM4G,EAAiBlF,EAAS+F,EAAK5F,kBACnED,KAAK,WACW,aAAZF,GACH/D,OAAO4G,QAAQC,UAAU,GAAI,GAAIhH,EAAIc,KAGtC6B,GACA,EACF,EACD,IAUD8G,WAAA,SAAWzJ,EAAKoJ,EAAiBc,EAAOhG,cAIvC,OAHA5B,KAAK8D,gBAAkBpG,EACvBsC,KAAKwE,UAAYxE,KAAK8D,gBAAgBrF,SAE3B2B,QAAQ,SAACC,GACnBuH,EAAM9B,SAASvE,SAEfiG,UAAEE,KAAK,cAAe,CACrB1F,KAAM6F,EAAKxE,kBACXxB,GAAI+F,EACJhG,QAAAA,IAGGiG,EAAK1C,gBACR0C,EAAKC,YAAYF,EAAMG,SAGpBF,EAAKtC,iBACRsC,EAAKG,WAAWJ,EAAMK,QAIP,aAAZrG,GAA0BlE,EAAIe,OAASmJ,EAAMM,UAChDrK,OAAO4G,QAAQ0D,aAAa,GAAI,GAAIP,EAAMM,UAG3CN,EAAM9B,SAASrF,MAAMqG,EAAiBlF,GACpCE,KAAK,WACL0F,UAAEE,KAAK,eAAgB,CACtB1F,KAAM6F,EAAKxE,kBACXxB,GAAI+F,EACJhG,QAAAA,IAGDiG,EAAKxE,kBAAoBuE,EACzBC,EAAKzE,iBAAkB,EACvByE,EAAKvD,WAAY,EACjBjE,GACA,EACF,EACD,IAODyH,YAAA,SAAYM,GAKX,IAJA,IAAMC,YAAiBD,GACjBE,EAAiBC,MAAMvG,KAAK9C,SAASsJ,iBAAiB,WAAWC,OAAOzI,KAAKmF,gBAG1EuD,EAAI,EAAGA,EAAIJ,EAAepK,OAAQwK,IAC1C,IAAK,IAAIC,EAAI,EAAGA,EAAIN,EAAWnK,OAAQyK,IACtC,GAAIL,EAAeI,GAAGzH,YAAcoH,EAAWM,GAAG1H,UAAW,CAC5DvC,EAAc4J,EAAeI,GAAI,UACjCL,EAAWO,OAAOD,EAAG,GACrB,KACA,CAIH,cAAqBN,kBACpBrJ,UAAsB,SAEvB,IAODgJ,WAAA,SAAWa,GAeV,IAdA,IAAMC,EAAgBP,MAAMvG,KAAK9C,SAASsJ,iBAAiB,2BAA2BC,OAAOzI,KAAKuF,iBAC5FwD,EAAsBR,MAAMvG,KAAK9C,SAASsJ,iBAAiB,UAAUC,OAAOzI,KAAKuF,iBAEjFyD,EAAkBH,EAAaJ,OAAO,SAAAQ,GAE3C,OAAKA,EAAGxK,OAEIqK,EAAcI,KAAK,SAACC,UAASA,EAAK1K,OAASwK,EAAGxK,IAA3B,WAC9BS,SAASE,KAAKgK,OAAOH,OAGtB,GAGQP,EAAI,EAAGA,EAAIK,EAAoB7K,OAAQwK,IAC/C,IAAK,IAAIC,EAAI,EAAGA,EAAIK,EAAgB9K,OAAQyK,IAC3C,GAAII,EAAoBL,GAAGzH,YAAc+H,EAAgBL,GAAG1H,UAAW,CACtEvC,EAAcqK,EAAoBL,GAAI,SACtCM,EAAgBJ,OAAOD,EAAG,GAC1B,KACA,CAIH,cAAoBK,kBACnBhK,UAAqB,QAEtB,IAMD2G,aAAA,SAAad,GACZ2C,UAAE6B,SAAS,QAASxE,EAAO7E,KAAKwD,SAChCgE,UAAEH,GAAG,WAAYxJ,OAAQmC,KAAKqE,YAE1BrE,KAAK+E,gBACRyC,UAAE6B,SAAS,mBAAoBxE,EAAO7E,KAAK2E,WAE5C,IAiFDyB,oHAAA,SAAM1I,EAAK4L,cAEV,YAFUA,IAAAA,GAAc,GAEpBtJ,KAAKuD,eAAef,IAAI9E,GAC3B,YAAY6F,eAAeZ,IAAIjF,GAGhC,IAAM6L,EAAU,IAAInJ,QAAQ,SAACC,EAASqG,GACrC,IAAI8C,EAEJpD,MAAM1I,EAAK,CACV+L,KAAM,cACNC,OAAQ,MACRC,QAAS,CAAE,mBAAoB,QAC/BC,YAAa,gBAEZ9H,KAAK,SAACuE,GAWN,OAVKA,EAASwD,KACbnD,EAAO,+CAEH4C,IACHzL,OAAOC,SAASW,KAAOf,IAIzB8L,EAAcnD,EAAS3I,IAEhB2I,EAASyD,MAChB,GACAhI,KAAK,SAACiI,OJvfczD,EIwfpBjG,EAAQ,CAAEiG,MJxfUA,EIwfKyD,EJvfN,iBAATzD,EAAoB/I,EAAOyM,gBAAgB1D,EAAM,aAAeA,GIufpC5I,IAAK8L,GAC3C,SACM,SAACtF,GACPwC,EAAOxC,GAEHoF,IACHzL,OAAOC,SAASW,KAAOf,EAExB,WACQ,WACRuM,EAAK1G,sBAAsB7F,EAC3B,EACF,GAID,OAFAsC,KAAKuD,eAAed,IAAI/E,EAAK6L,GAEtBA,CACP,KAODxC,iBAAA,SAAiBpF,SAChB,GAAIA,EACH,YAAYsD,YAAYtD,GAGzB,IAAMuI,WAAkBlK,KAAKkG,eAALiE,EAAavH,UAAU5C,KAAK8D,gBAAiB9D,KAAK4G,gBAE1E,OAAIsD,OACSjF,YAAYiF,QAGbzE,iBACZ,IAQDG,iBAAA,SAAiB/E,EAAMnD,GACtB,IAAMsD,EAAUH,EAAK6E,cAAc,oBAC7B9E,EAAWI,EAAQiD,QAAQmG,SAASlM,OAAS8B,KAAKgF,UAAUhE,EAAQiD,QAAQmG,UAAYpK,KAAKwF,gBAMnG,OAJK5E,GACJuD,QAAQC,sBAAsBpD,EAAQiD,QAAQmG,+FAGxC,CACNvJ,KAAAA,EACAG,QAAAA,EACAkH,SAAUxK,EACVsJ,UAAWhG,EAAQqJ,aAAa,qBAChCtC,QAAS/H,KAAKmF,eAAiBoD,MAAMvG,KAAKnB,EAAK2H,iBAAiB,WAAWC,OAAOzI,KAAKmF,gBAAkB,GACzG8C,OAAQjI,KAAKuF,gBAAkBgD,MAAMvG,KAAKnB,EAAK2H,iBAAiB,kCAAkCC,OAAOzI,KAAKuF,iBAAmB,GACjIzE,MAAOD,EAAKC,MACZgF,SAAU,IAAIlF,EAAS,CACtBX,QAASD,KAAKC,QACda,MAAOD,EAAKC,MACZE,QAAAA,EACAH,KAAAA,IAGF"} \ No newline at end of file diff --git a/package.json b/package.json index b6ce67a..5890633 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@unseenco/taxi", "description": "A modern page transition library which supports routing, preloading, and additional script reloading.", - "version": "1.6.0", + "version": "1.7.0", "license": "GPL-3.0-or-later", "source": "src/taxi.js", "main": "src/taxi.js", diff --git a/src/Core.d.ts b/src/Core.d.ts index f106f56..3ab70ba 100644 --- a/src/Core.d.ts +++ b/src/Core.d.ts @@ -73,6 +73,7 @@ export default class Core { raw: string; href: string; host: string; + search: string; hasHash: boolean; pathname: string; }; @@ -127,6 +128,7 @@ export default class Core { raw: string; href: string; host: string; + search: string; hasHash: boolean; pathname: string; }; diff --git a/src/Core.js b/src/Core.js index cdf855a..3fcf439 100644 --- a/src/Core.js +++ b/src/Core.js @@ -436,7 +436,11 @@ export default class Core { */ onPopstate = () => { // don't trigger for on-page anchors - if (window.location.pathname === this.currentLocation.pathname && !this.isPopping) { + if ( + window.location.pathname === this.currentLocation.pathname + && window.location.search === this.currentLocation.search + && !this.isPopping + ) { return false } diff --git a/src/helpers.d.ts b/src/helpers.d.ts index f9a4f6b..d34fc34 100644 --- a/src/helpers.d.ts +++ b/src/helpers.d.ts @@ -9,12 +9,13 @@ export function parseDom(html: string | Document): Document | any; * Extract details from a given URL string. Assumed to be on the current TLD. * * @param {string} url - * @return {{raw: string, href: string, host: string, hasHash: boolean, pathname: string}} + * @return {{raw: string, href: string, host: string, search: string, hasHash: boolean, pathname: string}} */ export function processUrl(url: string): { raw: string; href: string; host: string; + search: string; hasHash: boolean; pathname: string; }; diff --git a/src/helpers.js b/src/helpers.js index 4091163..a9fa31b 100644 --- a/src/helpers.js +++ b/src/helpers.js @@ -14,7 +14,7 @@ export function parseDom(html) { * Extract details from a given URL string. Assumed to be on the current TLD. * * @param {string} url - * @return {{raw: string, href: string, host: string, hasHash: boolean, pathname: string}} + * @return {{raw: string, href: string, host: string, search: string, hasHash: boolean, pathname: string}} */ export function processUrl(url) { const details = new URL(url, window.location.origin) @@ -24,6 +24,7 @@ export function processUrl(url) { hasHash: details.hash.length > 0, pathname: details.pathname, host: details.host, + search: details.search, raw: url, href: normalized || details.href }