Skip to content

Instantly share code, notes, and snippets.

@theadam
Created November 12, 2015 03:02
Show Gist options
  • Save theadam/bf54fb6e9d5518028c6e to your computer and use it in GitHub Desktop.
Save theadam/bf54fb6e9d5518028c6e to your computer and use it in GitHub Desktop.
requirebin sketch
// require() some stuff from npm (like you were using browserify)
// and then hit Run Code to run it on the right
var Router5 = require('router5').Router5;
var historyPlugin = require('router5-history');
var router = new Router5()
.addNode('one', '/home')
.addNode('two', '/about')
.addNode('three', '/contact')
.addNode('four', '/contact/:id')
.addNode('five', '/about/copywrite')
.usePlugin(historyPlugin())
.start();
['one', 'two', 'three', 'four', 'five'].forEach(function(v){
document.getElementById(v).addEventListener('click', function(){
router.navigate(v)
});
});
require=function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s}({1:[function(require,module,exports){"use strict";Object.defineProperty(exports,"__esModule",{value:true});var _extends=Object.assign||function(target){for(var i=1;i<arguments.length;i++){var source=arguments[i];for(var key in source){if(Object.prototype.hasOwnProperty.call(source,key)){target[key]=source[key]}}}return target};exports["default"]=asyncProcess;function asyncProcess(functions,_ref,callback){var isCancelled=_ref.isCancelled;var toState=_ref.toState;var fromState=_ref.fromState;var context=_ref.context;var allowBool=arguments.length<=3||arguments[3]===undefined?true:arguments[3];var remainingFunctions=Array.isArray(functions)?functions:Object.keys(functions);var initialFromState=_extends({},fromState);var isState=function isState(obj){return typeof obj==="object"&&obj.name!==undefined&&obj.params!==undefined&&obj.path!==undefined};var hasStateChanged=function hasStateChanged(state){return state.name!==toState.name||state.params!==toState.params||state.path!==toState.path};var processFn=function processFn(done){if(!remainingFunctions.length)return true;var isMapped=typeof remainingFunctions[0]==="string";var errVal=isMapped?remainingFunctions[0]:{};var stepFn=isMapped?functions[remainingFunctions[0]]:remainingFunctions[0];stepFn=context?stepFn.bind(context):stepFn;var len=stepFn.length;var res=stepFn(toState,fromState,done);if(allowBool&&typeof res==="boolean"){done(res?null:errVal)}else if(res&&typeof res.then==="function"){res.then(function(resVal){return done(null,resVal)},function(){return done(errVal)})}return false};var iterate=function iterate(err,val){if(err)callback(err);else{if(val&&isState(val)){if(hasStateChanged(val))console.error("[router5][transition] State values changed during transition process and ignored.");else toState=val}remainingFunctions=remainingFunctions.slice(1);next()}};var next=function next(){if(isCancelled()){callback(null)}else{var finished=processFn(iterate);if(finished)callback(null,toState)}};next()}module.exports=exports["default"]},{}],2:[function(require,module,exports){"use strict";Object.defineProperty(exports,"__esModule",{value:true});var constants={ROUTER_NOT_STARTED:"NOT_STARTED",ROUTER_ALREADY_STARTED:"ALREADY_STARTED",ROUTE_NOT_FOUND:"ROUTE_NOT_FOUND",SAME_STATES:"SAME_STATES",CANNOT_DEACTIVATE:"CANNOT_DEACTIVATE",CANNOT_ACTIVATE:"CANNOT_ACTIVATE",TRANSITION_ERR:"TRANSITION_ERR",TRANSITION_CANCELLED:"CANCELLED"};exports["default"]=constants;module.exports=exports["default"]},{}],3:[function(require,module,exports){"use strict";Object.defineProperty(exports,"__esModule",{value:true});function loggerPlugin(){var startGroup=function startGroup(){return console.group("Router transition")};var endGroup=function endGroup(){return console.groupEnd("Router transition")};return{name:"LOGGER",onStart:function onStart(){console.info("Router started")},onStop:function onStop(){console.info("Router stopped")},onTransitionStart:function onTransitionStart(toState,fromState){endGroup();startGroup();console.log("Transition started from state");console.log(fromState);console.log("To state");console.log(toState)},onTransitionCancel:function onTransitionCancel(toState,fromState){console.warn("Transition cancelled")},onTransitionError:function onTransitionError(toState,fromState,err){console.warn("Transition error with code "+err.code);endGroup()},onTransitionSuccess:function onTransitionSuccess(toState,fromState){console.log("Transition success");endGroup()}}}exports["default"]=loggerPlugin;module.exports=exports["default"]},{}],4:[function(require,module,exports){"use strict";Object.defineProperty(exports,"__esModule",{value:true});var _createClass=function(){function defineProperties(target,props){for(var i=0;i<props.length;i++){var descriptor=props[i];descriptor.enumerable=descriptor.enumerable||false;descriptor.configurable=true;if("value"in descriptor)descriptor.writable=true;Object.defineProperty(target,descriptor.key,descriptor)}}return function(Constructor,protoProps,staticProps){if(protoProps)defineProperties(Constructor.prototype,protoProps);if(staticProps)defineProperties(Constructor,staticProps);return Constructor}}();function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{"default":obj}}function _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function")}}var _routeNode=require("route-node");var _routeNode2=_interopRequireDefault(_routeNode);var _router5TransitionPath=require("router5.transition-path");var _router5TransitionPath2=_interopRequireDefault(_router5TransitionPath);var _transition2=require("./transition");var _transition3=_interopRequireDefault(_transition2);var _constants=require("./constants");var _constants2=_interopRequireDefault(_constants);var _logger=require("./logger");var _logger2=_interopRequireDefault(_logger);var makeState=function makeState(name,params,path){var state={};var setProp=function setProp(key,value){return Object.defineProperty(state,key,{value:value,enumerable:true})};setProp("name",name);setProp("params",params);setProp("path",path);return state};var Router5=function(){function Router5(routes){var _this=this;var opts=arguments.length<=1||arguments[1]===undefined?{}:arguments[1];_classCallCheck(this,Router5);this.started=false;this.mware=null;this._cbs={};this._cmps={};this._canAct={};this.lastStateAttempt=null;this.lastKnownState=null;this.rootNode=routes instanceof _routeNode2["default"]?routes:new _routeNode2["default"]("","",routes);this.options={useHash:false,hashPrefix:"",base:false,trailingSlash:0,autoCleanUp:true};Object.keys(opts).forEach(function(opt){return _this.options[opt]=opts[opt]});this.registeredPlugins={}}_createClass(Router5,[{key:"setOption",value:function setOption(opt,val){this.options[opt]=val;return this}},{key:"add",value:function add(routes){this.rootNode.add(routes);return this}},{key:"addNode",value:function addNode(name,path,canActivate){this.rootNode.addNode(name,path);if(canActivate)this._canAct[name]=canActivate;return this}},{key:"usePlugin",value:function usePlugin(plugin){var _this2=this;if(!plugin.name)console.warn("[router5.registerPlugin(plugin)] Missing property pluginName");var pluginMethods=["onStart","onStop","onTransitionSuccess","onTransitionStart","onTransitionError","onTransitionCancel"];var defined=pluginMethods.concat("init").some(function(method){return plugin[method]!==undefined});if(!defined)throw new Error("[router5] plugin "+plugin.name+" has none of the expected methods implemented");this.registeredPlugins[plugin.name]=plugin;if(plugin.init)plugin.init(this);pluginMethods.forEach(function(method){if(plugin[method]){_this2._addListener(method.toLowerCase().replace(/^on/,"$$").replace(/transition/,"$$"),plugin[method])}});return this}},{key:"useMiddleware",value:function useMiddleware(){this.mware=Array.prototype.slice.call(arguments);return this}},{key:"start",value:function start(){var _this3=this;var args=Array.prototype.slice.call(arguments);var lastArg=args.slice(-1)[0];var done=lastArg instanceof Function?lastArg:null;var startPath=undefined,startState=undefined;if(this.started){if(done)done({code:_constants2["default"].ROUTER_ALREADY_STARTED});return this}this.started=true;this._invokeListeners("$start");var opts=this.options;if(args.length>0){if(typeof args[0]==="string")startPath=args[0];if(typeof args[0]==="object")startState=args[0]}var cb=function cb(err,state){var invokeErrCb=arguments.length<=2||arguments[2]===undefined?true:arguments[2];if(done)done(err,state);if(!err)_this3._invokeListeners("$$success",state,null,{replace:true});if(err&&invokeErrCb)_this3._invokeListeners("$$error",state,null,err)};if(startPath===undefined&&startState===undefined&&this.getLocation){startPath=this.getLocation()}if(!startState){(function(){startState=startPath===undefined?null:_this3.matchPath(startPath);var navigateToDefault=function navigateToDefault(){return _this3.navigate(opts.defaultRoute,opts.defaultParams,{replace:true},function(err,state){return cb(err,state,false)})};if(startState){_this3.lastStateAttempt=startState;_this3._transition(_this3.lastStateAttempt,_this3.lastKnownState,function(err,state){if(!err){cb(null,state)}else if(opts.defaultRoute)navigateToDefault();else cb(err,null,false)})}else if(opts.defaultRoute){navigateToDefault()}else{cb({code:_constants2["default"].ROUTE_NOT_FOUND,path:startPath},null)}})()}else{this.lastKnownState=startState;cb(null,startState)}return this}},{key:"stop",value:function stop(){if(!this.started)return this;this.lastKnownState=null;this.lastStateAttempt=null;this.started=false;this._invokeListeners("$stop");return this}},{key:"getState",value:function getState(){return this.lastKnownState}},{key:"isActive",value:function isActive(name){var params=arguments.length<=1||arguments[1]===undefined?{}:arguments[1];var strictEquality=arguments.length<=2||arguments[2]===undefined?false:arguments[2];var ignoreQueryParams=arguments.length<=3||arguments[3]===undefined?true:arguments[3];var activeState=this.getState();if(!activeState)return false;if(strictEquality||activeState.name===name){return this.areStatesEqual(makeState(name,params),activeState,ignoreQueryParams)}return this.areStatesDescendants(makeState(name,params),activeState)}},{key:"areStatesEqual",value:function areStatesEqual(state1,state2){var _this4=this;var ignoreQueryParams=arguments.length<=2||arguments[2]===undefined?true:arguments[2];if(state1.name!==state2.name)return false;var getUrlParams=function getUrlParams(name){return _this4.rootNode.getSegmentsByName(name).map(function(segment){return segment.parser[ignoreQueryParams?"urlParams":"params"]}).reduce(function(params,p){return params.concat(p)},[])};var state1Params=getUrlParams(state1.name);var state2Params=getUrlParams(state2.name);return state1Params.length===state2Params.length&&state1Params.every(function(p){return state1.params[p]===state2.params[p]})}},{key:"areStatesDescendants",value:function areStatesDescendants(parentState,childState){var regex=new RegExp("^"+parentState.name+"\\.(.*)$");if(!regex.test(childState.name))return false;return Object.keys(parentState.params).every(function(p){return parentState.params[p]===childState.params[p]})}},{key:"_invokeListeners",value:function _invokeListeners(name){for(var _len=arguments.length,args=Array(_len>1?_len-1:0),_key=1;_key<_len;_key++){args[_key-1]=arguments[_key]}(this._cbs[name]||[]).forEach(function(cb){return cb.apply(undefined,args)})}},{key:"_addListener",value:function _addListener(name,cb,replace){this._cbs[name]=(this._cbs[name]||[]).concat(cb);return this}},{key:"registerComponent",value:function registerComponent(name,component){var warn=arguments.length<=2||arguments[2]===undefined?true:arguments[2];if(this._cmps[name]&&warn)console.warn("A component was alread registered for route node "+name+".");this._cmps[name]=component;return this}},{key:"canDeactivate",value:function canDeactivate(name,_canDeactivate){if(!this.options.autoCleanUp)throw new Error('[router.canDeactivate()] Cannot be used if "autoCleanUp" is set to false');this.registerComponent(name,{canDeactivate:function canDeactivate(toState,fromState){return _canDeactivate}},false);return this}},{key:"deregisterComponent",value:function deregisterComponent(name){this._cmps[name]=undefined}},{key:"canActivate",value:function canActivate(name,_canActivate){this._canAct[name]=_canActivate;return this}},{key:"buildUrl",value:function buildUrl(route,params){return this._buildUrl(this.buildPath(route,params))}},{key:"_buildUrl",value:function _buildUrl(path){return(this.options.base||"")+(this.options.useHash?"#"+this.options.hashPrefix:"")+path}},{key:"buildPath",value:function buildPath(route,params){return this.rootNode.buildPath(route,params)}},{key:"matchPath",value:function matchPath(path){var match=this.rootNode.matchPath(path,this.options.trailingSlash);return match?makeState(match.name,match.params,path):null}},{key:"urlToPath",value:function urlToPath(url){var match=url.match(/^(?:http|https)\:\/\/(?:[0-9a-z_\-\.\:]+?)(?=\/)(.*)$/);var path=match?match[1]:url;var pathParts=path.match(/^(.+?)(#.+?)?(\?.+)?$/);if(!pathParts)throw new Error("[router5] Could not parse url "+url);var pathname=pathParts[1];var hash=pathParts[2]||"";var search=pathParts[3]||"";var opts=this.options;return(opts.useHash?hash.replace(new RegExp("^#"+opts.hashPrefix),""):opts.base?pathname.replace(new RegExp("^"+opts.base),""):pathname)+search}},{key:"matchUrl",value:function matchUrl(url){return this.matchPath(this.urlToPath(url))}},{key:"_transition",value:function _transition(toState,fromState,done){var _this5=this;this.cancel();this._invokeListeners("$$start",toState,fromState);var tr=(0,_transition3["default"])(this,toState,fromState,function(err,state){state=state||toState;_this5._tr=null;if(err){if(err.code===_constants2["default"].TRANSITION_CANCELLED)_this5._invokeListeners("$$cancel",toState,fromState);else _this5._invokeListeners("$$error",toState,fromState,err);if(done)done(err);return}_this5.lastKnownState=state;if(done)done(null,state)});this._tr=tr;return function(){return!tr||tr()}}},{key:"cancel",value:function cancel(){if(this._tr)this._tr()}},{key:"navigate",value:function navigate(name,params,opts,done){if(params===undefined)params={};var _this6=this;if(opts===undefined)opts={};if(!this.started){if(done)done({code:_constants2["default"].ROUTER_NOT_STARTED});return}var path=this.buildPath(name,params);if(!path){var err={code:_constants2["default"].ROUTE_NOT_FOUND};if(done)done(err);this._invokeListeners("$$error",null,this.lastKnownState,err);return}var toState=makeState(name,params,path);this.lastStateAttempt=toState;var sameStates=this.lastKnownState?this.areStatesEqual(this.lastKnownState,this.lastStateAttempt,false):false;if(sameStates&&!opts.reload){var err={code:_constants2["default"].SAME_STATES};if(done)done(err);this._invokeListeners("$$error",toState,this.lastKnownState,err);return}var fromState=sameStates?null:this.lastKnownState;return this._transition(toState,sameStates?null:this.lastKnownState,function(err,state){if(err){if(done)done(err);return}_this6._invokeListeners("$$success",toState,fromState,opts);if(done)done(null,state)})}}]);return Router5}();Router5.ERR=_constants2["default"];Router5.transitionPath=_router5TransitionPath2["default"];Router5.loggerPlugin=_logger2["default"];exports["default"]=Router5;module.exports=exports["default"]},{"./constants":2,"./logger":3,"./transition":5,"route-node":6,"router5.transition-path":8}],5:[function(require,module,exports){"use strict";Object.defineProperty(exports,"__esModule",{value:true});var _extends=Object.assign||function(target){for(var i=1;i<arguments.length;i++){var source=arguments[i];for(var key in source){if(Object.prototype.hasOwnProperty.call(source,key)){target[key]=source[key]}}}return target};function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{"default":obj}}function _defineProperty(obj,key,value){if(key in obj){Object.defineProperty(obj,key,{value:value,enumerable:true,configurable:true,writable:true})}else{obj[key]=value}return obj}var _router5TransitionPath=require("router5.transition-path");var _router5TransitionPath2=_interopRequireDefault(_router5TransitionPath);var _async=require("./async");var _async2=_interopRequireDefault(_async);var _constants=require("./constants");var _constants2=_interopRequireDefault(_constants);exports["default"]=transition;var nameToIDs=function nameToIDs(name){return name.split(".").reduce(function(ids,name){return ids.concat(ids.length?ids[ids.length-1]+"."+name:name)},[])};function transition(router,toState,fromState,callback){var cancelled=false;var isCancelled=function isCancelled(){return cancelled};var cancel=function cancel(){return cancelled=true};var done=function done(err,state){if(!err&&!isCancelled()&&router.options.autoCleanUp){(function(){var activeSegments=nameToIDs(toState.name);Object.keys(router._cmps).filter(function(name){if(activeSegments.indexOf(name)===-1)router.deregisterComponent(name)})})()}callback(isCancelled()?{code:_constants2["default"].TRANSITION_CANCELLED}:err,state||toState)};var _transitionPath=(0,_router5TransitionPath2["default"])(toState,fromState);var toDeactivate=_transitionPath.toDeactivate;var toActivate=_transitionPath.toActivate;var canDeactivate=function canDeactivate(toState,fromState,cb){var canDeactivateFunctionMap=toDeactivate.filter(function(name){return router._cmps[name]&&router._cmps[name].canDeactivate}).reduce(function(fnMap,name){return _extends({},fnMap,_defineProperty({},name,router._cmps[name].canDeactivate))},{});(0,_async2["default"])(canDeactivateFunctionMap,{isCancelled:isCancelled,toState:toState,fromState:fromState},function(err){return cb(err?{code:_constants2["default"].CANNOT_DEACTIVATE,segment:err}:null)})};var canActivate=function canActivate(toState,fromState,cb){var canActivateFunctionMap=toActivate.filter(function(name){return router._canAct[name]}).reduce(function(fnMap,name){return _extends({},fnMap,_defineProperty({},name,router._canAct[name]))},{});(0,_async2["default"])(canActivateFunctionMap,{isCancelled:isCancelled,toState:toState,fromState:fromState},function(err){return cb(err?{code:_constants2["default"].CANNOT_ACTIVATE,segment:err}:null)})};var middlewareFn=router.mware;var middleware=function middleware(toState,fromState,cb){var mwareFunction=Array.isArray(router.mware)?router.mware:[router.mware];(0,_async2["default"])(mwareFunction,{isCancelled:isCancelled,toState:toState,fromState:fromState,context:{cancel:cancel,router:router}},function(err,state){var errObj=err?typeof err==="object"?err:{error:err}:null;cb(err?_extends({code:_constants2["default"].TRANSITION_ERR},errObj):null,state||toState)})};var pipeline=(fromState?[canDeactivate]:[]).concat(canActivate).concat(middlewareFn?middleware:[]);(0,_async2["default"])(pipeline,{isCancelled:isCancelled,toState:toState,fromState:fromState},done);return cancel}module.exports=exports["default"]},{"./async":1,"./constants":2,"router5.transition-path":8}],6:[function(require,module,exports){"use strict";Object.defineProperty(exports,"__esModule",{value:true});var _createClass=function(){function defineProperties(target,props){for(var i=0;i<props.length;i++){var descriptor=props[i];descriptor.enumerable=descriptor.enumerable||false;descriptor.configurable=true;if("value"in descriptor)descriptor.writable=true;Object.defineProperty(target,descriptor.key,descriptor)}}return function(Constructor,protoProps,staticProps){if(protoProps)defineProperties(Constructor.prototype,protoProps);if(staticProps)defineProperties(Constructor,staticProps);return Constructor}}();function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{"default":obj}}function _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function")}}var _pathParser=require("path-parser");var _pathParser2=_interopRequireDefault(_pathParser);var isSerialisable=function isSerialisable(val){return val!==undefined&&val!==null&&val!==""};var removeQueryParamsFromPath=function removeQueryParamsFromPath(path,params){if(path.indexOf("?")===-1)return path;var splitPath=path.split("?");var pathPart=splitPath[0];var searchPart=splitPath[1];var remainingSearchParams=searchPart.split("&").reduce(function(obj,p){var splitParam=p.split("=");var key=splitParam[0];var val=splitParam[1];if(params.indexOf(key)===-1)obj[key]=val||"";return obj},{});var remainingSearchPart=Object.keys(remainingSearchParams).map(function(p){return[p].concat(isSerialisable(remainingSearchParams[p])?remainingSearchParams[p]:[])}).map(function(p){return p.join("=")}).join("&");return pathPart+(remainingSearchPart?"?"+remainingSearchPart:"")};var RouteNode=function(){function RouteNode(){var name=arguments.length<=0||arguments[0]===undefined?"":arguments[0];var path=arguments.length<=1||arguments[1]===undefined?"":arguments[1];var childRoutes=arguments.length<=2||arguments[2]===undefined?[]:arguments[2];_classCallCheck(this,RouteNode);this.name=name;this.path=path;this.parser=path?new _pathParser2["default"](path):null;this.children=[];this.add(childRoutes);return this}_createClass(RouteNode,[{key:"add",value:function add(route){var _this=this;if(route===undefined||route===null)return;if(route instanceof Array){route.forEach(function(r){return _this.add(r)});return}if(!(route instanceof RouteNode)&&!(route instanceof Object)){throw new Error("RouteNode.add() expects routes to be an Object or an instance of RouteNode.")}if(route instanceof Object){if(!route.name||!route.path){throw new Error("RouteNode.add() expects routes to have a name and a path defined.")}route=new RouteNode(route.name,route.path,route.children)}if(this.children.map(function(child){return child.name}).indexOf(route.name)!==-1){throw new Error('Alias "'+route.name+'" is already defined in route node')}if(this.children.map(function(child){return child.path}).indexOf(route.path)!==-1){throw new Error('Path "'+route.path+'" is already defined in route node')}var names=route.name.split(".");if(names.length===1){this.children.push(route);this.children.sort(function(a,b){if(a.path==="/")return 1;if(b.path==="/")return-1;var aHasParams=a.parser.hasUrlParams||a.parser.hasSpatParam;var bHasParams=b.parser.hasUrlParams||b.parser.hasSpatParam;if(!aHasParams&&!bHasParams){return a.path&&b.path?a.path.length<b.path.length?1:-1:0}if(aHasParams&&!bHasParams)return 1;if(!aHasParams&&bHasParams)return-1;if(!a.parser.hasSpatParam&&b.parser.hasSpatParam)return-1;if(!b.parser.hasSpatParam&&a.parser.hasSpatParam)return 1;var aSegments=(a.path.match(/\//g)||[]).length;var bSegments=(b.path.match(/\//g)||[]).length;if(aSegments<bSegments)return 1;return 0})}else{var segments=this.getSegmentsByName(names.slice(0,-1).join("."));if(segments){segments[segments.length-1].add(new RouteNode(names[names.length-1],route.path,route.children))}else{throw new Error("Could not add route named '"+route.name+"', parent is missing.")}}return this}},{key:"addNode",value:function addNode(name,params){this.add(new RouteNode(name,params));return this}},{key:"getSegmentsByName",value:function getSegmentsByName(routeName){var findSegmentByName=function findSegmentByName(name,routes){var filteredRoutes=routes.filter(function(r){return r.name===name});return filteredRoutes.length?filteredRoutes[0]:undefined};var segments=[];var names=routeName.split(".");var routes=this.children;var matched=names.every(function(name){var segment=findSegmentByName(name,routes);if(segment){routes=segment.children;segments.push(segment);return true}return false});return matched?segments:null}},{key:"getSegmentsMatchingPath",value:function getSegmentsMatchingPath(path){var trailingSlash=arguments.length<=1||arguments[1]===undefined?false:arguments[1];var matchChildren=function matchChildren(nodes,pathSegment,segments){var _loop=function(i){var child=nodes[i];var match=child.parser.partialMatch(pathSegment);var remainingPath=undefined,remainingSearch=undefined;if(!match&&trailingSlash){match=child.parser.match(pathSegment,true);remainingPath=""}else if(match){var consumedPath=child.parser.build(match,{ignoreSearch:true});remainingPath=removeQueryParamsFromPath(pathSegment.replace(consumedPath,""),child.parser.queryParams);if(trailingSlash&&remainingPath==="/"&&!/\/$/.test(consumedPath)){remainingPath=""}}if(match){segments.push(child);Object.keys(match).forEach(function(param){return segments.params[param]=match[param]});if(!remainingPath.length){return{v:segments}}if(!child.children.length){return{v:null}}return{v:matchChildren(child.children,remainingPath,segments)}}};for(var i in nodes){var _ret=_loop(i);if(typeof _ret==="object")return _ret.v}return null};var startingNodes=this.parser?[this]:this.children;var segments=[];segments.params={};return matchChildren(startingNodes,path,segments)}},{key:"getPathFromSegments",value:function getPathFromSegments(segments){return segments?segments.map(function(segment){return segment.path}).join(""):null}},{key:"getPath",value:function getPath(routeName){return this.getPathFromSegments(this.getSegmentsByName(routeName))}},{key:"buildPathFromSegments",value:function buildPathFromSegments(segments){var params=arguments.length<=1||arguments[1]===undefined?{}:arguments[1];if(!segments)return null;var searchParams=segments.filter(function(s){return s.parser.hasQueryParams}).map(function(s){return s.parser.queryParams});var searchPart=!searchParams.length?null:searchParams.reduce(function(queryParams,params){return queryParams.concat(params)}).filter(function(p){return Object.keys(params).indexOf(p)!==-1}).map(function(p){return _pathParser2["default"].serialise(p,params[p])}).join("&");return segments.map(function(segment){return segment.parser.build(params,{ignoreSearch:true})}).join("")+(searchPart?"?"+searchPart:"")}},{key:"buildPath",value:function buildPath(routeName){var params=arguments.length<=1||arguments[1]===undefined?{}:arguments[1];return this.buildPathFromSegments(this.getSegmentsByName(routeName),params)}},{key:"getMatchPathFromSegments",value:function getMatchPathFromSegments(segments){if(!segments||!segments.length)return null;var name=segments.map(function(segment){return segment.name}).join(".");var params=segments.params;return{name:name,params:params}}},{key:"matchPath",value:function matchPath(path){var trailingSlash=arguments.length<=1||arguments[1]===undefined?false:arguments[1];return this.getMatchPathFromSegments(this.getSegmentsMatchingPath(path,trailingSlash))}}]);return RouteNode}();exports["default"]=RouteNode;module.exports=exports["default"]},{"path-parser":7}],7:[function(require,module,exports){"use strict";Object.defineProperty(exports,"__esModule",{value:true});var _createClass=function(){function defineProperties(target,props){for(var i=0;i<props.length;i++){var descriptor=props[i];descriptor.enumerable=descriptor.enumerable||false;descriptor.configurable=true;if("value"in descriptor)descriptor.writable=true;Object.defineProperty(target,descriptor.key,descriptor)}}return function(Constructor,protoProps,staticProps){if(protoProps)defineProperties(Constructor.prototype,protoProps);if(staticProps)defineProperties(Constructor,staticProps);return Constructor}}();function _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function")}}var defaultOrConstrained=function defaultOrConstrained(match){return"("+(match?match.replace(/(^<|>$)/g,""):"[a-zA-Z0-9-_.~]+")+")"};var rules=[{name:"url-parameter",pattern:/^:([a-zA-Z0-9-_]*[a-zA-Z0-9]{1})(<(.+?)>)?/,regex:function regex(match){return new RegExp(defaultOrConstrained(match[2]))}},{name:"url-parameter-splat",pattern:/^\*([a-zA-Z0-9-_]*[a-zA-Z0-9]{1})/,regex:/([^\?]*)/},{name:"url-parameter-matrix",pattern:/^\;([a-zA-Z0-9-_]*[a-zA-Z0-9]{1})(<(.+?)>)?/,regex:function regex(match){return new RegExp(";"+match[1]+"="+defaultOrConstrained(match[2]))}},{name:"query-parameter",pattern:/^(?:\?|&)(?:\:)?([a-zA-Z0-9-_]*[a-zA-Z0-9]{1})/},{name:"delimiter",pattern:/^(\/|\?)/,regex:function regex(match){return new RegExp("\\"+match[0])}},{name:"sub-delimiter",pattern:/^(\!|\&|\-|_|\.|;)/,regex:function regex(match){return new RegExp(match[0])}},{name:"fragment",pattern:/^([0-9a-zA-Z]+?)/,regex:function regex(match){return new RegExp(match[0])}}];var tokenise=function tokenise(str){var tokens=arguments.length<=1||arguments[1]===undefined?[]:arguments[1];var matched=rules.some(function(rule){var match=str.match(rule.pattern);if(!match)return false;tokens.push({type:rule.name,match:match[0],val:match.slice(1,2),otherVal:match.slice(2),regex:rule.regex instanceof Function?rule.regex(match):rule.regex});if(match[0].length<str.length)tokens=tokenise(str.substr(match[0].length),tokens);return true});if(!matched){throw new Error("Could not parse path.")}return tokens};var optTrailingSlash=function optTrailingSlash(source,trailingSlash){if(!trailingSlash)return source;return source.replace(/\\\/$/,"")+"(?:\\/)?"};var appendQueryParam=function appendQueryParam(params,param){var val=arguments.length<=2||arguments[2]===undefined?"":arguments[2];var existingVal=params[param];if(existingVal===undefined)params[param]=val;else params[param]=Array.isArray(existingVal)?existingVal.concat(val):[existingVal,val];return params};var parseQueryParams=function parseQueryParams(path){var searchPart=path.split("?")[1];if(!searchPart)return{};return searchPart.split("&").map(function(_){return _.split("=")}).reduce(function(obj,m){return appendQueryParam(obj,m[0],m[1])},{})};var toSerialisable=function toSerialisable(val){return val!==undefined&&val!==null&&val!==""?"="+val:""};var _serialise=function _serialise(key,val){return Array.isArray(val)?val.map(function(v){return _serialise(key,v)}).join("&"):key+toSerialisable(val)};var Path=function(){_createClass(Path,null,[{key:"createPath",value:function createPath(path){return new Path(path)}},{key:"serialise",value:function serialise(key,val){return _serialise(key,val)}}]);function Path(path){_classCallCheck(this,Path);if(!path)throw new Error("Please supply a path");this.path=path;this.tokens=tokenise(path);this.hasUrlParams=this.tokens.filter(function(t){return/^url-parameter/.test(t.type)}).length>0;this.hasSpatParam=this.tokens.filter(function(t){return/splat$/.test(t.type)}).length>0;this.hasMatrixParams=this.tokens.filter(function(t){return/matrix$/.test(t.type)}).length>0;this.hasQueryParams=this.tokens.filter(function(t){return t.type==="query-parameter"}).length>0;this.urlParams=!this.hasUrlParams?[]:this.tokens.filter(function(t){return/^url-parameter/.test(t.type)}).map(function(t){return t.val.slice(0,1)}).reduce(function(r,v){return r.concat(v)});this.queryParams=!this.hasQueryParams?[]:this.tokens.filter(function(t){return t.type==="query-parameter"}).map(function(t){return t.val}).reduce(function(r,v){return r.concat(v)});this.params=this.urlParams.concat(this.queryParams);this.source=this.tokens.filter(function(t){return t.regex!==undefined}).map(function(r){return r.regex.source}).join("")}_createClass(Path,[{key:"_urlMatch",value:function _urlMatch(path,regex){var _this=this;var match=path.match(regex);if(!match)return null;else if(!this.urlParams.length)return{};return match.slice(1,this.urlParams.length+1).reduce(function(params,m,i){params[_this.urlParams[i]]=m;return params},{})}},{key:"match",value:function match(path){var _this2=this;var trailingSlash=arguments.length<=1||arguments[1]===undefined?0:arguments[1];var source=optTrailingSlash(this.source,trailingSlash);var match=this._urlMatch(path,new RegExp("^"+source+(this.hasQueryParams?"\\?.*$":"$")));if(!match||!this.hasQueryParams)return match;var queryParams=parseQueryParams(path);var unexpectedQueryParams=Object.keys(queryParams).filter(function(p){return _this2.queryParams.indexOf(p)===-1});if(unexpectedQueryParams.length===0){Object.keys(queryParams).forEach(function(p){return match[p]=queryParams[p]});return match}return null}},{key:"partialMatch",value:function partialMatch(path){var _this3=this;var trailingSlash=arguments.length<=1||arguments[1]===undefined?0:arguments[1];var source=optTrailingSlash(this.source,trailingSlash);var match=this._urlMatch(path,new RegExp("^"+source));if(!match)return match;if(!this.hasQueryParams)return match;var queryParams=parseQueryParams(path);Object.keys(queryParams).filter(function(p){return _this3.queryParams.indexOf(p)>=0}).forEach(function(p){return appendQueryParam(match,p,queryParams[p]);
});return match}},{key:"build",value:function build(){var params=arguments.length<=0||arguments[0]===undefined?{}:arguments[0];var opts=arguments.length<=1||arguments[1]===undefined?{ignoreConstraints:false,ignoreSearch:false}:arguments[1];if(this.urlParams.some(function(p){return params[p]===undefined}))throw new Error("Missing parameters");if(!opts.ignoreConstraints){var constraintsPassed=this.tokens.filter(function(t){return/^url-parameter/.test(t.type)&&!/-splat$/.test(t.type)}).every(function(t){return new RegExp("^"+defaultOrConstrained(t.otherVal[0])+"$").test(params[t.val])});if(!constraintsPassed)throw new Error("Some parameters are of invalid format")}var base=this.tokens.filter(function(t){return t.type!=="query-parameter"}).map(function(t){if(t.type==="url-parameter-matrix")return";"+t.val[0]+"="+params[t.val[0]];return/^url-parameter/.test(t.type)?params[t.val[0]]:t.match}).join("");if(opts.ignoreSearch)return base;var searchPart=this.queryParams.filter(function(p){return Object.keys(params).indexOf(p)!==-1}).map(function(p){return _serialise(p,params[p])}).join("&");return base+(searchPart?"?"+searchPart:"")}}]);return Path}();exports["default"]=Path;module.exports=exports["default"]},{}],8:[function(require,module,exports){"use strict";Object.defineProperty(exports,"__esModule",{value:true});function transitionPath(toState,fromState){function nameToIDs(name){return name.split(".").reduce(function(ids,name){return ids.concat(ids.length?ids[ids.length-1]+"."+name:name)},[])}var i=undefined;var fromStateIds=fromState?nameToIDs(fromState.name):[];var toStateIds=nameToIDs(toState.name);var maxI=Math.min(fromStateIds.length,toStateIds.length);if(fromState&&fromState.name===toState.name){i=Math.max(maxI-1,0)}else{for(i=0;i<maxI;i+=1){if(fromStateIds[i]!==toStateIds[i])break}}var toDeactivate=fromStateIds.slice(i).reverse();var toActivate=toStateIds.slice(i);var intersection=fromState&&i>0?fromStateIds[i-1]:"";return{intersection:intersection,toDeactivate:toDeactivate,toActivate:toActivate}}exports["default"]=transitionPath;module.exports=exports["default"]},{}],router5:[function(require,module,exports){"use strict";Object.defineProperty(exports,"__esModule",{value:true});function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{"default":obj}}var _router5=require("./router5");var _router52=_interopRequireDefault(_router5);var _routeNode=require("route-node");var _routeNode2=_interopRequireDefault(_routeNode);exports["default"]={Router5:_router52["default"],RouteNode:_routeNode2["default"]};module.exports=exports["default"]},{"./router5":4,"route-node":6}]},{},[]);require=function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s}({1:[function(require,module,exports){"use strict";Object.defineProperty(exports,"__esModule",{value:true});var identity=function identity(arg){return function(){return arg}};var noop=function noop(){};var isBrowser=typeof window!=="undefined";var getBase=function getBase(){return window.location.pathname.replace(/\/$/,"")};var pushState=function pushState(state,title,path){return window.history.pushState(state,title,path)};var replaceState=function replaceState(state,title,path){return window.history.replaceState(state,title,path)};var addPopstateListener=function addPopstateListener(fn){return window.addEventListener("popstate",fn)};var removePopstateListener=function removePopstateListener(fn){return window.removeEventListener("popstate",fn)};var getLocation=function getLocation(opts){var path=opts.useHash?window.location.hash.replace(new RegExp("^#"+opts.hashPrefix),""):window.location.pathname.replace(new RegExp("^"+opts.base),"");return path+window.location.search};var browser={};if(isBrowser){browser={getBase:getBase,pushState:pushState,replaceState:replaceState,addPopstateListener:addPopstateListener,removePopstateListener:removePopstateListener,getLocation:getLocation}}else{browser={getBase:identity(""),pushState:noop,replaceState:noop,addPopstateListener:noop,removePopstateListener:noop,getLocation:identity("")}}exports["default"]=browser;module.exports=exports["default"]},{}],"router5-history":[function(require,module,exports){"use strict";Object.defineProperty(exports,"__esModule",{value:true});var _extends=Object.assign||function(target){for(var i=1;i<arguments.length;i++){var source=arguments[i];for(var key in source){if(Object.prototype.hasOwnProperty.call(source,key)){target[key]=source[key]}}}return target};var _browser=require("./browser");var pluginName="HISTORY";function historyPlugin(){var router=undefined;function updateBrowserState(state,url,replace){if(replace)(0,_browser.replaceState)(state,"",url);else(0,_browser.pushState)(state,"",url)}function onPopState(evt){var newState=!evt.state||!evt.state.name;var state=newState?router.matchPath((0,_browser.getLocation)(router.options)):evt.state;var _router$options=router.options;var defaultRoute=_router$options.defaultRoute;var defaultParams=_router$options.defaultParams;if(!state){router.navigate(defaultRoute,defaultParams,{reload:true,replace:true});return}if(router.lastKnownState&&router.areStatesEqual(state,router.lastKnownState,true)){return}var fromState=_extends({},router.getState());router._transition(state,fromState,function(err,toState){if(err){if(err==="CANNOT_DEACTIVATE"){var url=router.buildUrl(router.lastKnownState.name,router.lastKnownState.params);if(!newState){updateBrowserState(state,url,true)}}else{router.navigate(defaultRoute,defaultParams,{reload:true,replace:true})}}else{router._invokeListeners("$$success",toState,fromState,{replace:!newState})}})}function init(target){router=target;router.getLocation=function(){return(0,_browser.getLocation)(router.options)}}function onStart(){if(router.options.useHash&&!router.options.base){router.options.base=(0,_browser.getBase)()}(0,_browser.addPopstateListener)(onPopState)}function onStop(){(0,_browser.removePopstateListener)(onPopState)}function onTransitionSuccess(toState,fromState,opts){updateBrowserState(toState,router.buildUrl(toState.name,toState.params),opts.replace||opts.reload)}return{name:pluginName,init:init,onStart:onStart,onStop:onStop,onTransitionSuccess:onTransitionSuccess,onPopState:onPopState}}exports["default"]=historyPlugin;module.exports=exports["default"]},{"./browser":1}]},{},[]);var Router5=require("router5").Router5;var historyPlugin=require("router5-history");var router=(new Router5).addNode("one","/home").addNode("two","/about").addNode("three","/contact").addNode("four","/contact/:id").addNode("five","/about/copywrite").usePlugin(historyPlugin()).start();["one","two","three","four","five"].forEach(function(v){document.getElementById(v).addEventListener("click",function(){router.navigate(v)})});
{
"name": "requirebin-sketch",
"version": "1.0.0",
"dependencies": {
"router5": "1.0.0",
"router5-history": "1.0.0"
}
}
<!-- contents of this file will be placed inside the <body> -->
<button id="one">one</button>
<button id="two">two</button>
<button id="three">three</button>
<button id="four">four</button>
<button id="five">five</button>
<!-- contents of this file will be placed inside the <head> -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment