spa-hash-router
Version:
Simple hash router for Single Page Application (SPA)
6 lines (5 loc) • 4.18 kB
JavaScript
//#Router v2.1.5
//Copyright (c) 2015-2018 Valerii Zinchenko
//Licensed under MIT (http://valerii-zinchenko.gitlab.io/spa-hash-router/blob/master/LICENSE.txt)
//All source files are available at: http://gitlab.com/valerii-zinchenko/spa-hash-router
!function(t,e){void 0===t&&void 0!==window&&(t=window),"function"==typeof define&&define.amd?define([],function(){return t.HashRouter=e()}):"object"==typeof module&&module.exports?module.exports=e():t.HashRouter=e()}(this,function(){"use strict";var h=Object.prototype.toString;function p(t,e){return h.call(t)==="[object "+e+"]"}function e(t){if(!this)throw new Error('"new" operator is required');if(null!==e.instance)return e.instance;p(t,"Object")&&(p(t.prefix,"String")&&(this._prefix=t.prefix),p(t.fallbackRoute,"String")&&(this._fallbackRoute=t.fallbackRoute),p(t.before,"Function")&&(this._before=t.before),p(t.after,"Function")&&(this._after=t.after),p(t.routes,"Object")&&this.add(t.routes),p(t.map,"Object")&&p(t.context,"Object")&&this.addContextualMap(t.map,t.context)),e.instance=this}return e.instance=null,e.prototype.hashRegExp=/(?:(\#.*)(?=\?))|(\#.*)/,e.prototype.queryRegExp=/(\?.*)(?=\#)(?:\#.*(\?.*))?|(\?.*)+?/,e.prototype._routingMap={},e.prototype._prefix="",e.prototype._fallbackRoute="",e.prototype._history=[],e.prototype._before=function(){},e.prototype._after=function(){},e.prototype.add=function(t,e){var o=arguments.length;switch(o){case 1:if(!p(t,"Object"))throw new Error('Incorrect type of the single argument. Expected "Object", but got '+h.call(t));for(var r in t)this.add(r,t[r]);return;case 2:if(!p(t,"String"))throw new Error('Incorrect type of "route". Expected "String", but got '+h.call(t));if(!p(e,"Array")){if(!p(e,"Function"))throw new Error('Incorrect type of "methods". Expected "Array" or "Function", but got '+h.call(e));e=[e]}break;default:throw new Error("Incorrect amount of input arguments. Expected 1 or 2, but got "+o)}this._routingMap[t]||(this._routingMap[t]={regExp:new RegExp(this._preprocessRouteName(t,this._prefix)),methods:[]});for(var n=this._routingMap[t].methods,i=0,a=e.length;i<a;i++)n.push(e[i])},e.prototype.addContextualMap=function(t,o){var e=arguments.length;if(2!==e)throw new Error("Incorrect amount of input arguments. Expected 2, but got "+e);if(!p(t,"Object"))throw new Error('Incorrect type of "routingMap". Expected "Object", but got '+h.call(t));var r={};for(var n in t)r[n]=[],p(t[n],"String")&&(t[n]=[t[n]]),t[n].forEach(function(t){var e=o[t];e&&p(e,"Function")&&r[n].push(e.bind(o))});this.add(r)},e.prototype.start=function(t){window.addEventListener("hashchange",this.onHashChange.bind(this)),t&&this._hashChange(this._getHash(t),this._getQuery(t))},e.prototype.onHashChange=function(t){this._hashChange(this._getHash(t.newURL),this._getQuery(t.newURL))},e.prototype.routeTo=function(t,e){p(e,"Object")&&(t+=this.object2Query(e)),location.hash=t},e.prototype.back=function(){this._history.pop(),0===this._history.length&&this._fallbackRoute?this.routeTo(this._prefix+this._fallbackRoute):window.history.back()},e.prototype._hashChange=function(t,e){var o,r,n;for(var i in this._routingMap)if((n=this._routingMap[i]).regExp.test(t)){o=n.regExp.exec(t),r=n.methods;break}r&&0!==r.length?(this._history[this._history.length-2]===t?this._history.pop():this._history.push(t),(o=o.slice(1)).push(this.query2Object(e)),this._before(),r.forEach(function(t){t.apply(null,o)}),this._after()):0===this._history.length&&this.routeTo(this._prefix+this._fallbackRoute)},e.prototype.query2Object=function(t){return t&&"?"===t[0]&&t[1]?(t='{"'+(t=(t=(t=t.replace(/\?(?!&|;)|\?&|\?;|&$|;$/g,"")).replace(/=/g,'":"')).replace(/&|;/g,'","'))+'"}',JSON.parse(t)):{}},e.prototype.object2Query=function(t){var e,o=[];for(var r in t)(e=t[r])&&o.push(r+"="+e);return 0===o.length?"":"?"+o.join(";")},e.prototype._preprocessRouteName=function(t,e){return"^#"+(e=e?"(?:"+e+")?":"")+(t=t.replace(/\:[\w\-\.]+/g,"([\\w\\-\\.]+/?)"))+"/?$"},e.prototype._getHash=function(t){var e=this.hashRegExp.exec(t)||[];return e[1]||e[2]||"#"},e.prototype._getQuery=function(t){var e,o=this.queryRegExp.exec(t)||[];return o[1]?(e=o[1],o[2]&&(e+=";"+o[2].slice(1))):o[3]&&(e=o[3]),e},e});