{"version":3,"file":"highway.module.js","sources":["../node_modules/tiny-emitter/index.js","../src/renderer.js","../src/helpers.js","../src/core.js","../src/transition.js","../src/highway.js"],"sourcesContent":["function E () {\n // Keep this empty so it's easier to inherit from\n // (via https://github.com/lipsmack from https://github.com/scottcorgan/tiny-emitter/issues/3)\n}\n\nE.prototype = {\n on: function (name, callback, ctx) {\n var e = this.e || (this.e = {});\n\n (e[name] || (e[name] = [])).push({\n fn: callback,\n ctx: ctx\n });\n\n return this;\n },\n\n once: function (name, callback, ctx) {\n var self = this;\n function listener () {\n self.off(name, listener);\n callback.apply(ctx, arguments);\n };\n\n listener._ = callback\n return this.on(name, listener, ctx);\n },\n\n emit: function (name) {\n var data = [].slice.call(arguments, 1);\n var evtArr = ((this.e || (this.e = {}))[name] || []).slice();\n var i = 0;\n var len = evtArr.length;\n\n for (i; i < len; i++) {\n evtArr[i].fn.apply(evtArr[i].ctx, data);\n }\n\n return this;\n },\n\n off: function (name, callback) {\n var e = this.e || (this.e = {});\n var evts = e[name];\n var liveEvents = [];\n\n if (evts && callback) {\n for (var i = 0, len = evts.length; i < len; i++) {\n if (evts[i].fn !== callback && evts[i].fn._ !== callback)\n liveEvents.push(evts[i]);\n }\n }\n\n // Remove event from queue to prevent memory leak\n // Suggested by https://github.com/lazd\n // Ref: https://github.com/scottcorgan/tiny-emitter/commit/c6ebfaa9bc973b33d110a84a307742b7cf94c953#commitcomment-5024910\n\n (liveEvents.length)\n ? e[name] = liveEvents\n : delete e[name];\n\n return this;\n }\n};\n\nmodule.exports = E;\nmodule.exports.TinyEmitter = E;\n","/**\n * @file Highway default renderer that handle DOM stuffs.\n * @author Anthony Du Pont \n */\n\nexport default class Renderer {\n\n /**\n * @arg {object} properties — Set of properties (slug, page, view,...)\n * @constructor\n */\n constructor(properties) {\n // We get the view.\n this.wrap = document.querySelector('[data-router-wrapper]');\n\n // We save properties of the renderer\n this.properties = properties;\n\n // We get our transition we will use later to show/hide our view.\n this.Transition = properties.transition ? new properties.transition.class(this.wrap, properties.transition.name) : null;\n }\n\n /**\n * Renderer initialization.\n */\n setup() {\n // These both methods have to be called at least once on first load.\n this.onEnter && this.onEnter();\n this.onEnterCompleted && this.onEnterCompleted();\n }\n\n /**\n * Add view in DOM, then remove previous view\n */\n add() {\n // We setup the DOM for our [data-router-view]\n this.wrap.insertAdjacentHTML('beforeend', this.properties.view.outerHTML);\n }\n\n /**\n * Update document informations\n */\n update() {\n // Now we update all the informations in the DOM we need!\n // We update the title\n document.title = this.properties.page.title;\n }\n\n /**\n * Add the view in DOM and play an `in` transition if one is defined.\n *\n * @param {object} datas - Set of datas\n * @return {object} Promise\n */\n show(datas) {\n return new Promise(async resolve => {\n // Update DOM.\n this.update();\n\n // The `onEnter` method if set is called everytime the view is appended\n // to the DOM. This let you do some crazy stuffs at this right moment.\n this.onEnter && this.onEnter();\n\n // The transition is set in your custom renderer with a getter called\n // `transition` that should return the transition object you want to\n // apply to you view. We call the `in` step of this one right now!\n this.Transition && await this.Transition.show(datas);\n\n // The `onEnterCompleted` method if set in your custom renderer is called\n // everytime a transition is over if set. Otherwise it's called right after\n // the `onEnter` method.\n this.onEnterCompleted && this.onEnterCompleted();\n\n // We resolve the Promise.\n resolve();\n });\n }\n\n /**\n * Play an `out` transition if one is defined and remove the view from DOM.\n *\n * @param {object} datas - Set of datas\n * @return {object} Promise\n */\n hide(datas) {\n return new Promise(async resolve => {\n // The `onLeave` method if set in your custom renderer is called everytime\n // before a view will be removed from the DOM. This let you do some stuffs\n // right before the view isn't available anymore.\n this.onLeave && this.onLeave();\n\n // We call the `out` step of your transition right now!\n this.Transition && await this.Transition.hide(datas);\n\n // The `onLeaveCompleted` method if set in your custom renderer is called\n // everytime a view is completely removed from the DOM.\n this.onLeaveCompleted && this.onLeaveCompleted();\n\n // Resolve Promise\n resolve();\n });\n }\n}\n","/**\n * @file Highway helper methods used all acrosse the script.\n * @author Anthony Du Pont \n */\n\n// Dependencies\nimport Renderer from './renderer';\n\n// Constants\nconst PARSER = new window.DOMParser();\n\n// Highway Helpers\nexport default class Helpers {\n\n /**\n * @arg {object} renderers — List of renderers\n * @arg {object} transitions — List of transitions\n * @constructor\n */\n constructor(renderers, transitions) {\n this.renderers = renderers;\n this.transitions = transitions;\n }\n\n /**\n * Get origin of an URL\n *\n * @arg {string} url — URL to match\n * @return {string} Origin of URL or `null`\n * @static\n */\n getOrigin(url) {\n const match = url.match(/(https?:\\/\\/[\\w\\-.]+)/);\n return match ? match[1].replace(/https?:\\/\\//, '') : null;\n }\n\n /**\n * Get pathname of an URL\n *\n * @arg {string} url — URL to match\n * @return {string} Pathname of URL or `null`\n * @static\n */\n getPathname(url) {\n const match = url.match(/https?:\\/\\/.*?(\\/[\\w_\\-./]+)/);\n return match ? match[1] : '/';\n }\n\n /**\n * Get anchor in an URL\n *\n * @arg {string} url — URL to match\n * @return {string} Anchor in URL or `null`\n * @static\n */\n getAnchor(url) {\n const match = url.match(/(#.*)$/);\n return match ? match[1] : null;\n }\n\n /**\n * Get search in URL.\n *\n * @arg {string} url — URL to match\n * @return {object} Search in URL formatted as an object or `null`\n * @static\n */\n getParams(url) {\n const match = url.match(/\\?([\\w_\\-.=&]+)/);\n\n if (!match) {\n return null;\n }\n\n const search = match[1].split('&');\n const object = {};\n\n for (let i = 0; i < search.length; i++) {\n const part = search[i].split('=');\n const { 0: key } = part;\n const { 1: value } = part;\n\n object[key] = value;\n }\n\n return object;\n }\n\n /**\n * Get page's DOM from page HTML\n *\n * @arg {string} page — Page HTML\n * @return {string} Page DOM\n * @static\n */\n getDOM(page) {\n return typeof page === 'string' ? PARSER.parseFromString(page, 'text/html') : page;\n }\n\n /**\n * Get view element from page DOM\n *\n * @arg {string} page — Page DOM\n * @return {object} View element or `null`\n * @static\n */\n getView(page) {\n return page.querySelector('[data-router-view]');\n }\n\n /**\n * Get view's slug from view element\n *\n * @arg {string} view — [data-router-view] DOM\n * @return {string} Page slug or `null`\n * @static\n */\n getSlug(view) {\n return view.getAttribute('data-router-view');\n }\n\n /**\n * Get page renderer\n *\n * @arg {string} slug — Renderer's slug\n * @return {object} Single renderer or default one\n * @static\n */\n getRenderer(slug) {\n // Return Default\n if (!this.renderers) {\n return Promise.resolve(Renderer);\n }\n\n // Return Renderer\n if (slug in this.renderers) {\n const renderer = this.renderers[slug];\n\n if (typeof renderer === 'function' && !Renderer.isPrototypeOf(renderer)) {\n return Promise.resolve(renderer()).then(({ default: cons }) => cons);\n }\n\n if (typeof renderer.then === 'function') {\n return Promise.resolve(renderer).then(({ default: cons }) => cons);\n }\n\n return Promise.resolve(renderer);\n }\n\n // Return Default\n return Promise.resolve(Renderer);\n }\n\n /**\n * Get page transition\n *\n * @arg {string} slug — Transition slug\n * @return {object} Single transition or `null`\n * @static\n */\n getTransition(slug) {\n if (!this.transitions) {\n return null;\n }\n\n if (slug in this.transitions) {\n // Return Transition\n return { class: this.transitions[slug], name: slug };\n }\n\n if ('default' in this.transitions) {\n // Return Transition\n return { class: this.transitions['default'], name: 'default' };\n }\n\n return null;\n }\n\n /**\n * Get all required properties for a context.\n *\n * @arg {object} context – DOM context\n * @return {object} Properties\n */\n getProperties(context) {\n const page = this.getDOM(context);\n const view = this.getView(page);\n const slug = this.getSlug(view);\n const renderer = this.getRenderer(slug, this.renderers);\n const transition = this.getTransition(slug, this.transitions);\n\n return {\n page,\n view,\n slug,\n renderer,\n transition\n };\n }\n\n /**\n * Get state of an URL.\n *\n * @arg {string} url — URL to decompose\n * @return {object} State\n */\n getLocation(url) {\n return {\n href: url,\n anchor: this.getAnchor(url),\n origin: this.getOrigin(url),\n params: this.getParams(url),\n pathname: this.getPathname(url)\n };\n }\n}\n","/**\n * @file Highway core that handle all history stuffs.\n * @author Anthony Du Pont \n */\nimport Emitter from 'tiny-emitter';\nimport Helpers from './helpers';\n\nexport default class Core extends Emitter {\n\n /**\n * @arg {object} opts — User options\n * @arg {object} opts.renderers — List of renderers\n * @arg {object} opts.transitions — List of transitions\n * @extends Emitter\n * @constructor\n */\n constructor({ renderers, transitions } = {}) {\n // Extends the Emitter constructor in order to be able to use its features\n // and send custom events all along the script.\n super();\n\n // Helpers.\n this.Helpers = new Helpers(renderers, transitions);\n\n // Prep contextual transition info.\n this.Transitions = transitions;\n this.Contextual = false;\n\n // Properties & state.\n this.location = this.Helpers.getLocation(window.location.href);\n this.properties = this.Helpers.getProperties(document.cloneNode(true));\n\n // Status variables.\n this.popping = false;\n this.running = false;\n\n // Trigger Element\n this.trigger = null;\n\n // Cache\n this.cache = new Map();\n this.cache.set(this.location.href, this.properties);\n\n // Get the page renderer and properly setup it.\n this.properties.renderer.then(Renderer => {\n this.From = new Renderer(this.properties);\n this.From.setup();\n });\n\n // Events variables.\n this._navigate = this.navigate.bind(this);\n\n // Listen the `popstate` on the window to run the router each time an\n // history entry changes. Basically everytime the backward/forward arrows\n // are triggered by the user.\n window.addEventListener('popstate', this.popState.bind(this));\n\n // Get all elligible links.\n this.links = document.querySelectorAll('a:not([target]):not([data-router-disabled])');\n\n // Event attachement\n this.attach(this.links);\n }\n\n /**\n * Attach `click` event on links.\n *\n * @param {(array|nodeList)} links - Links to use\n */\n attach(links) {\n for (const link of links) {\n link.addEventListener('click', this._navigate);\n }\n }\n\n /**\n * Detach `click` event on links.\n *\n * @param {(array|nodeList)} links - Links to use\n */\n detach(links) {\n for (const link of links) {\n link.removeEventListener('click', this._navigate);\n }\n }\n\n /**\n * Click method called on `click` event.\n *\n * @arg {object} e - `click` event\n */\n navigate(e) {\n if (!(e.metaKey || e.ctrlKey)) {\n // Prevent default `click`\n e.preventDefault();\n\n // Check to see if this navigation will use a contextual transition\n const contextual = e.currentTarget.hasAttribute('data-transition') ? e.currentTarget.dataset.transition : false;\n\n // We have to redirect to our `href` using Highway\n // There we set up the contextual transition, so this and Core.redirect can pass in either transition name or false\n this.redirect(e.currentTarget.href, contextual, e.currentTarget);\n }\n }\n\n /**\n * Redirect to URL\n *\n * @param {string} href - URL\n * @param {(object|boolean)} contextual - If the transition is changing on the fly\n * @param {(object|string)} trigger - The trigger element or a string\n */\n redirect(href, contextual = false, trigger = 'script') {\n // Save Trigger Element\n this.trigger = trigger;\n\n // When our URL is different from the current location `href` and no other\n // navigation is running for the moment we are allowed to start a new one.\n // But if the URL containes anchors or if the origin is different we force\n // the hard reloading of the page to avoid serious errors.\n if (!this.running && href !== this.location.href) {\n // We temporary store the future location.\n const location = this.Helpers.getLocation(href);\n\n // Set contextual transition values if applicable\n this.Contextual = false;\n\n if (contextual) {\n this.Contextual = this.Transitions[contextual].prototype;\n this.Contextual.name = contextual;\n }\n\n if (location.origin !== this.location.origin || location.anchor && location.pathname === this.location.pathname) {\n // We redirect when origins are differents or when there is an anchor.\n window.location.href = href;\n\n } else {\n this.location = location;\n\n // Now all our conditions are passed we can update our location and do\n // what we need to do before fetching it.\n this.beforeFetch();\n\n }\n }\n }\n\n /**\n * Watch history entry changes.\n */\n popState() {\n // Save Trigger Element\n this.trigger = 'popstate';\n\n // A contextual transition only effects the transition when a certain link is clicked, not when navigating via browser buttons\n this.Contextual = false;\n\n // We temporary store the future location.\n const location = this.Helpers.getLocation(window.location.href);\n\n // When users navigate using the browser buttons we check if the locations\n // have no anchors and that our locations are different.\n if (this.location.pathname !== location.pathname || !this.location.anchor && !location.anchor) {\n this.popping = true;\n this.location = location;\n\n // If everything is fine we can save our location and do what we need to\n // do before fetching it.\n this.beforeFetch();\n\n } else {\n // Update Location\n this.location = location;\n\n }\n }\n\n /**\n * Update DOM on `click` event.\n */\n pushState() {\n if (!this.popping) {\n window.history.pushState(this.location, '', this.location.href);\n }\n }\n\n /**\n * Fetch the page from URL\n *\n * @return {string} Fetch response\n */\n async fetch() {\n const response = await fetch(this.location.href, {\n mode: 'same-origin',\n method: 'GET',\n headers: { 'X-Requested-With': 'Highway' },\n credentials: 'same-origin'\n });\n\n // We have to checked if the fetch response is OK otherwise we have to force\n // the hard reloading of the page because we might have an error.\n if (response.status >= 200 && response.status < 300) {\n return response.text();\n }\n\n window.location.href = this.location.href;\n }\n\n /**\n * Do some tests before HTTP requests to optimize pipeline.\n */\n async beforeFetch() {\n // Push State\n this.pushState();\n\n // We lock the navigation to avoid multiples clicks that could overload the\n // navigation process meaning that if the a navigation is running the user\n // cannot trigger a new one while the previous one is running.\n this.running = true;\n\n // We emit an event right before hiding the current view to create a hook\n // for developers that want to do stuffs when an elligible link is clicked.\n this.emit('NAVIGATE_OUT', {\n from: {\n page: this.From.properties.page,\n view: this.From.properties.view\n },\n trigger: this.trigger,\n location: this.location\n });\n\n // Transition Datas\n const datas = {\n trigger: this.trigger,\n contextual: this.Contextual\n };\n\n // We have to verify our cache in order to save some HTTPRequests. If we\n // don't use any caching system everytime we would come back to a page we\n // already saw we will have to fetch it again and it's pointless.\n if (this.cache.has(this.location.href)) {\n // We wait until the view is hidden.\n await this.From.hide(datas);\n\n // Get Properties\n this.properties = this.cache.get(this.location.href);\n\n } else {\n // We wait till all our Promises are resolved.\n const results = await Promise.all([\n this.fetch(),\n this.From.hide(datas)\n ]);\n\n // Now everything went fine we can extract the properties of the view we\n // successfully fetched and keep going.\n this.properties = this.Helpers.getProperties(results[0]);\n\n // We cache our result\n // eslint-disable-next-line\n this.cache.set(this.location.href, this.properties);\n\n }\n\n this.afterFetch();\n }\n\n /**\n * Push page in DOM\n */\n async afterFetch() {\n // We are calling the renderer attached to the view we just fetched and we\n // are adding the [data-router-view] in our DOM.\n const Renderer = await this.properties.renderer;\n\n this.To = new Renderer(this.properties);\n this.To.add();\n\n // We then emit a now event right before the view is shown to create a hook\n // for developers who want to make stuff before the view is visible.\n this.emit('NAVIGATE_IN', {\n to: {\n page: this.To.properties.page,\n view: this.To.wrap.lastElementChild\n },\n trigger: this.trigger,\n location: this.location\n });\n\n // We wait for the view transition to be over before resetting some variables\n // and reattaching the events to all the new elligible links in our DOM.\n await this.To.show({\n trigger: this.trigger,\n contextual: this.Contextual\n });\n\n this.popping = false;\n this.running = false;\n\n // Detach Event on Links\n this.detach(this.links);\n\n // Get all elligible links.\n this.links = document.querySelectorAll('a:not([target]):not([data-router-disabled])');\n\n // Attach Event on Links\n this.attach(this.links);\n\n // Finally we emit a last event to create a hook for developers who want to\n // make stuff when the navigation has ended.\n this.emit('NAVIGATE_END', {\n to: {\n page: this.To.properties.page,\n view: this.To.wrap.lastElementChild\n },\n from: {\n page: this.From.properties.page,\n view: this.From.properties.view\n },\n trigger: this.trigger,\n location: this.location\n });\n\n // Last but not least we swap the From and To renderers for future navigations.\n this.From = this.To;\n\n // Reset Trigger\n this.trigger = null;\n }\n}\n","/**\n * @file Highway default transition that handle DOM animations.\n * @author Anthony Du Pont \n */\nexport default class Transition {\n\n /**\n * @arg {object} wrap — [data-router-wrapper] node\n * @arg {object} name — Transition name\n * @constructor\n */\n constructor(wrap, name) {\n // The [data-router-wrapper] is the only main information we need since the role of\n // the transition is to show/hide the required DOM elements.\n this.wrap = wrap;\n\n // Save transition name for later.\n this.name = name;\n }\n\n /**\n * Add the view in DOM and play an `in` transition if one is defined.\n *\n * @return {object} Promise\n * @param {object} datas - Set of datas\n */\n show({ trigger, contextual }) {\n // Get View\n const to = this.wrap.lastElementChild;\n const from = this.wrap.firstElementChild;\n\n // Promise\n return new Promise(resolve => {\n // The `in` method in encapsulated in the `show` method make transition\n // code easier to write. This way you don't have to define any Promise\n // in your transition code and focus on the transition itself.\n if (!contextual) {\n // Change Attributes\n to.setAttribute('data-transition-in', this.name);\n to.removeAttribute('data-transition-out', this.name);\n\n // Call transition attached to the view.\n this.in && this.in({ to, from, trigger, done: resolve });\n\n } else {\n // Change Attributes\n to.setAttribute('data-transition-in', contextual.name);\n to.removeAttribute('data-transition-out', contextual.name);\n\n // Call the contextual transition.\n contextual.in && contextual.in({ to, from, trigger, done: resolve });\n\n }\n });\n }\n\n /**\n * Play an `out` transition if one is defined and remove the view from DOM.\n *\n * @return {object} Promise\n * @param {object} datas - Set of datas\n */\n hide({ trigger, contextual }) {\n // Get view\n const from = this.wrap.firstElementChild;\n\n // Promise\n return new Promise(resolve => {\n // The `out` method in encapsulated in the `hide` method make transition\n // code easier to write. This way you don't have to define any Promise\n // in your transition code and focus on the transition itself.\n if (!contextual) {\n // Change Attributes\n from.setAttribute('data-transition-out', this.name);\n from.removeAttribute('data-transition-in', this.name);\n\n // Call the transition attached to the view.\n this.out && this.out({ from, trigger, done: resolve });\n\n } else {\n // Change Attributes\n from.setAttribute('data-transition-out', contextual.name);\n from.removeAttribute('data-transition-in', contextual.name);\n\n // Call the contextual transition.\n contextual.out && contextual.out({ from, trigger, done: resolve });\n\n }\n });\n }\n}\n","/**\n * @file Highway object containing all parts of the script.\n * @author Anthony Du Pont \n */\nimport Core from './core';\nimport Helpers from './helpers';\nimport Renderer from './renderer';\nimport Transition from './transition';\n\n// Highway Version\nconsole.log('Highway v2.2.0');\n\n// Export Highway\nexport default {\n Core,\n Helpers,\n Renderer,\n Transition\n};\n"],"names":["E","prototype","on","name","callback","ctx","e","this","push","fn","once","self","listener","off","apply","arguments","_","emit","data","slice","call","evtArr","i","len","length","evts","liveEvents","Renderer","constructor","properties","wrap","document","querySelector","Transition","transition","class","setup","onEnter","onEnterCompleted","add","insertAdjacentHTML","view","outerHTML","update","title","page","show","datas","Promise","resolve","_this","hide","onLeaveCompleted","_this2","onLeave","const","PARSER","window","DOMParser","Helpers","renderers","transitions","getOrigin","url","match","replace","getPathname","getAnchor","getParams","search","split","object","part","getDOM","parseFromString","getView","getSlug","getAttribute","getRenderer","slug","renderer","isPrototypeOf","then","getTransition","getProperties","context","getLocation","href","anchor","origin","params","pathname","Core","Transitions","Contextual","location","cloneNode","popping","running","trigger","cache","Map","set","From","_navigate","navigate","bind","addEventListener","popState","links","querySelectorAll","attach","detach","removeEventListener","metaKey","ctrlKey","preventDefault","contextual","currentTarget","hasAttribute","dataset","redirect","beforeFetch","pushState","history","fetch","mode","method","headers","credentials","response","status","text","afterFetch","from","has","get","all","results","_this3","To","to","lastElementChild","Emitter","firstElementChild","setAttribute","removeAttribute","in","done","out","console","log"],"mappings":"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"}