├── .gitignore ├── .travis.yml ├── router.core.js ├── router.js ├── test ├── support │ ├── helper.js │ └── function-bind.js ├── route.test.js └── router.test.js ├── .babelrc ├── karma.conf.js ├── examples ├── some-tags.html ├── example-02.html ├── redux │ ├── index.html │ ├── common.js │ ├── app.html │ └── app.js └── example-01.html ├── LICENSE ├── webpack.config.js ├── package.json ├── README.md ├── dist ├── router.core.min.js ├── router.min.js ├── router.core.js ├── router.core.js.map └── router.js.map └── src └── router.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | npm-debug.log 3 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "iojs" 4 | - "node" -------------------------------------------------------------------------------- /router.core.js: -------------------------------------------------------------------------------- 1 | var Router = require('./src/router.js'); 2 | module.exports = Router; -------------------------------------------------------------------------------- /router.js: -------------------------------------------------------------------------------- 1 | var riot = require('riot'); 2 | var route = require('riot-route'); 3 | var Router = require('./src/router.js'); 4 | var router = Router.create({route: route}); 5 | if (window) { 6 | window.router = router; 7 | } 8 | module.exports = Router; 9 | 10 | -------------------------------------------------------------------------------- /test/support/helper.js: -------------------------------------------------------------------------------- 1 | var riot = require('riot'); 2 | var route = require('riot-route'); 3 | var Router = require('../../src/router'); 4 | var router = Router.create({route: route}); 5 | router.start(); 6 | 7 | module.exports = { 8 | riot: riot, 9 | router: router, 10 | Router: Router 11 | }; 12 | -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": [ 3 | "transform-es2015-template-literals", 4 | "transform-es2015-literals", 5 | "transform-es2015-function-name", 6 | "transform-es2015-arrow-functions", 7 | "transform-es2015-block-scoped-functions", 8 | "transform-es2015-classes", 9 | "transform-es2015-object-super", 10 | "transform-es2015-shorthand-properties", 11 | "transform-es2015-for-of", 12 | "transform-es2015-sticky-regex", 13 | "transform-es2015-unicode-regex", 14 | "transform-es2015-constants", 15 | "transform-es2015-spread", 16 | "transform-es2015-parameters", 17 | "transform-es2015-destructuring", 18 | "transform-es2015-block-scoping", 19 | "transform-es2015-typeof-symbol", 20 | "transform-es2015-modules-commonjs", 21 | "transform-regenerator", 22 | "transform-es2015-modules-umd" 23 | ] 24 | } -------------------------------------------------------------------------------- /karma.conf.js: -------------------------------------------------------------------------------- 1 | var extend = require('extend'); 2 | 3 | module.exports = function(config) { 4 | config.set({ 5 | frameworks: ['mocha'], 6 | plugins: [ 7 | 'karma-mocha', 8 | 'karma-mocha-reporter', 9 | 'karma-phantomjs-launcher', 10 | 'karma-webpack', 11 | 'karma-sourcemap-loader' 12 | ], 13 | files: [ 14 | 'test/support/function-bind.js', 15 | 'test/**/*.test.js' 16 | ], 17 | webpack: extend(require('./webpack.config'), { 18 | devtool: 'inline-source-map', 19 | externals: {} 20 | }), 21 | webpackMiddleware: { 22 | noInfo: true 23 | }, 24 | preprocessors: { 25 | 'test/*.test.js': ['webpack', 'sourcemap'], 26 | 'test/**/*.test.js': ['webpack', 'sourcemap'] 27 | }, 28 | browsers: [ 29 | 'PhantomJS' 30 | ], 31 | reporters: ['mocha'] 32 | }); 33 | }; 34 | -------------------------------------------------------------------------------- /examples/some-tags.html: -------------------------------------------------------------------------------- 1 | 2 | Current router.current.uri = '{router.current.uri}' 3 | 4 | 5 | 6 | router.on('route:updated', function() { 7 | this.update(); 8 | }.bind(this)); 9 | 10 | 11 | 12 | 19 | 20 | 21 | 22 | Page '{ router.current.uri }' not found! 23 | 24 | 25 | 26 | Home! 27 | 28 | 29 | 30 |
id={opts.id}
31 |
a={opts.a}
32 |
b={opts.b}
33 |
router.current={JSON.stringify(router.current, null, 2)}
34 |
35 | 36 | -------------------------------------------------------------------------------- /test/support/function-bind.js: -------------------------------------------------------------------------------- 1 | // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind 2 | // https://github.com/ariya/phantomjs/issues/10522 3 | if (!Function.prototype.bind) { 4 | Function.prototype.bind = function(oThis) { 5 | if (typeof this !== 'function') { 6 | // closest thing possible to the ECMAScript 5 7 | // internal IsCallable function 8 | throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable'); 9 | } 10 | 11 | var aArgs = Array.prototype.slice.call(arguments, 1), 12 | fToBind = this, 13 | fNOP = function() {}, 14 | fBound = function() { 15 | return fToBind.apply(this instanceof fNOP 16 | ? this 17 | : oThis, 18 | aArgs.concat(Array.prototype.slice.call(arguments))); 19 | }; 20 | 21 | if (this.prototype) { 22 | // native functions don't have a prototype 23 | fNOP.prototype = this.prototype; 24 | } 25 | fBound.prototype = new fNOP(); 26 | 27 | return fBound; 28 | }; 29 | } 30 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Gabriel Moreira 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | var webpack = require('webpack'); 2 | var configs = []; 3 | var config = { 4 | entry: { 5 | 'router': __dirname + '/router.js', 6 | 'router.core': __dirname + '/router.core.js' 7 | }, 8 | output: { 9 | path: __dirname + '/dist', 10 | publicPath: '/dist/', 11 | filename: '[name].js', 12 | library: 'Router', 13 | libraryTarget: "umd" 14 | }, 15 | externals: { 16 | "riot": "riot" 17 | }, 18 | module: { 19 | loaders: [{ 20 | test: /\.jsx?$/, 21 | exclude: /node_modules/, 22 | loader: 'babel-loader', 23 | query: { 24 | presets: ['es2015'], 25 | cacheDirectory: true 26 | } 27 | }] 28 | }, 29 | plugins: [] 30 | }; 31 | if (!process.env.DISABLE_SOURCEMAP) { 32 | config.devtool = 'source-map'; 33 | } 34 | configs.push(config); 35 | 36 | if (process.env.COMPRESS) { 37 | var extend = require('extend'); 38 | var newConfig = extend(true, {}, config); 39 | newConfig.output.filename = '[name].min.js'; 40 | newConfig.plugins.push( 41 | new webpack.optimize.UglifyJsPlugin({ 42 | compressor: { 43 | warnings: false 44 | } 45 | }) 46 | ); 47 | configs.push(newConfig); 48 | } 49 | 50 | module.exports = (configs.length > 1) ? configs : config; 51 | -------------------------------------------------------------------------------- /examples/example-02.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Router Simple Sample 7 | 8 | 9 | 10 | 13 | 14 | 15 | 18 | 19 | 20 | 23 | 28 | 29 | 30 | 31 | 32 | 33 | 36 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /examples/redux/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Redux App Example 7 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /test/route.test.js: -------------------------------------------------------------------------------- 1 | var assert = require('assert'), 2 | helper = require('./support/helper'); 3 | var riot = helper.riot, 4 | router = helper.router, 5 | Router = helper.Router; 6 | 7 | var Route = Router.Route; 8 | var NotFoundRoute = Router.NotFoundRoute; 9 | var DefaultRoute = Router.DefaultRoute; 10 | var Request = Router._.Request; 11 | var Response = Router._.Response; 12 | 13 | riot.tag('need-data', '{ opts.someData }', function (opts) { 14 | }); 15 | 16 | describe('router.navigateTo (test is not working...)', function() { 17 | var tag; 18 | var someData = 'the data i need'; 19 | 20 | before(function () { 21 | var route = document.createElement('route'); 22 | route.setAttribute('some-data', someData); 23 | document.body.appendChild(route); 24 | tag = riot.mount('route')[0]; 25 | router.routes([ 26 | new Route({tag: 'static'}), 27 | new Route({tag: 'need-data'}), 28 | new Route({path: '/dynamic', tag: function () { return 'dynamic'; }}), 29 | new Route({path: '/dynamic-api', tag: function () { 30 | return {tag: 'dynamic-api', api: {}}; 31 | }}) 32 | ]); 33 | router.start(); 34 | }); 35 | 36 | it('works with static tags', function() { 37 | router.navigateTo('/static'); 38 | assert.ok(document.querySelector('static')); 39 | }); 40 | 41 | it('works with dynamic tags', function() { 42 | router.navigateTo('/dynamic'); 43 | assert.ok(document.querySelector('dynamic')); 44 | }); 45 | 46 | it('works with dynamic tags and api', function() { 47 | router.navigateTo('/dynamic-api'); 48 | assert.ok(document.querySelector('dynamic-api')); 49 | }); 50 | 51 | it('passes data to the mounted tag', function() { 52 | router.navigateTo('/need-data'); 53 | assert.equal(tag.instance.opts.someData, someData); 54 | }); 55 | }); 56 | -------------------------------------------------------------------------------- /examples/redux/common.js: -------------------------------------------------------------------------------- 1 | function CreateSimpleApp(config) { 2 | var context = riot.observable(); 3 | 4 | function register() { 5 | if (config.utils) 6 | context.utils = config.utils(context); 7 | if (config.reducers) { 8 | var initialState = null; 9 | if (config.state) initialState = config.state(context); 10 | var reducers = Redux.combineReducers(config.reducers(context)); 11 | context.store = Redux.createStore(reducers, initialState, window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()); 12 | context.getState = context.store.getState; 13 | context.dispatch = function(type, payload, meta) { 14 | var event = {type: type}; 15 | if (payload) event.payload = payload; 16 | if (meta) event.meta = meta; 17 | context.store.dispatch(event); 18 | console.log(event); 19 | context.trigger(event.type, event.payload, event.meta, event); 20 | } 21 | } 22 | if (config.actions) 23 | context.actions = config.actions(context); 24 | if (config.routes) 25 | context.routes = config.routes(context); 26 | } 27 | 28 | function start() { 29 | if (context.utils) { 30 | riot.mixin({ 31 | utils: context.utils 32 | }); 33 | } 34 | if (context.store) { 35 | riot.mixin(RiotStateUpdater.StoreMixin(context.store)); 36 | } 37 | if (context.actions) { 38 | riot.mixin({ 39 | actions: context.actions 40 | }); 41 | } 42 | riot.util.tmpl.errorHandler = function (err) { 43 | console.error("[WARN]", err.message + ' in ' + err.riotData.tagName) // your error logic here 44 | } 45 | riot.mount('*'); 46 | console.log("mounted"); 47 | if (context.routes) { 48 | if (Object.prototype.toString.call(context.routes) === '[object Array]') 49 | router.routes(context.routes); 50 | else 51 | router.route(context.routes); 52 | router.start(); 53 | console.log("route started"); 54 | } 55 | } 56 | 57 | register(); 58 | start(); 59 | 60 | return context; 61 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "riot-router", 3 | "version": "0.9.7", 4 | "description": "A routing solution for Riot", 5 | "main": "dist/router.min.js", 6 | "directories": { 7 | "example": "examples", 8 | "test": "test" 9 | }, 10 | "dependencies": { 11 | "extend": "^3.0.0", 12 | "riot": "^3.0.7", 13 | "riot-route": "^3.0.2" 14 | }, 15 | "peerDependencies": { 16 | "extend": "^3.0.0", 17 | "riot": "^3.0.7", 18 | "riot-route": "^3.0.2" 19 | }, 20 | "devDependencies": { 21 | "babel-core": "^6.14.0", 22 | "babel-loader": "^6.2.5", 23 | "babel-plugin-transform-es2015-arrow-functions": "^6.8.0", 24 | "babel-plugin-transform-es2015-block-scoped-functions": "^6.8.0", 25 | "babel-plugin-transform-es2015-block-scoping": "^6.14.0", 26 | "babel-plugin-transform-es2015-classes": "^6.14.0", 27 | "babel-plugin-transform-es2015-constants": "^6.1.4", 28 | "babel-plugin-transform-es2015-destructuring": "^6.9.0", 29 | "babel-plugin-transform-es2015-for-of": "^6.8.0", 30 | "babel-plugin-transform-es2015-function-name": "^6.9.0", 31 | "babel-plugin-transform-es2015-literals": "^6.8.0", 32 | "babel-plugin-transform-es2015-modules-commonjs": "^6.14.0", 33 | "babel-plugin-transform-es2015-modules-umd": "^6.12.0", 34 | "babel-plugin-transform-es2015-object-super": "^6.8.0", 35 | "babel-plugin-transform-es2015-parameters": "^6.11.4", 36 | "babel-plugin-transform-es2015-shorthand-properties": "^6.8.0", 37 | "babel-plugin-transform-es2015-spread": "^6.3.14", 38 | "babel-plugin-transform-es2015-sticky-regex": "^6.8.0", 39 | "babel-plugin-transform-es2015-template-literals": "^6.8.0", 40 | "babel-plugin-transform-es2015-typeof-symbol": "^6.8.0", 41 | "babel-plugin-transform-es2015-unicode-regex": "^6.11.0", 42 | "babel-plugin-transform-regenerator": "^6.14.0", 43 | "babel-preset-es2015": "^6.14.0", 44 | "imports-loader": "^0.7.0", 45 | "karma": "^1.2.0", 46 | "karma-mocha": "^1.1.1", 47 | "karma-mocha-reporter": "^2.1.0", 48 | "karma-phantomjs-launcher": "^1.0.2", 49 | "karma-sourcemap-loader": "^0.3.7", 50 | "karma-webpack": "^2.0.1", 51 | "mocha": "^3.0.2", 52 | "node-libs-browser": "^2.0.0", 53 | "phantomjs": "^2.1.7", 54 | "webpack": "^1.13.2", 55 | "webpack-dev-server": "^1.15.1" 56 | }, 57 | "scripts": { 58 | "test": "node_modules/.bin/karma start --single-run", 59 | "test:watch": "node_modules/.bin/karma start --auto-watch", 60 | "watch": "webpack --watch", 61 | "build": "COMPRESS=1 webpack", 62 | "start": "webpack-dev-server", 63 | "prepublish": "npm run build && npm test" 64 | }, 65 | "repository": { 66 | "type": "git", 67 | "url": "git+https://github.com/gabrielmoreira/riot-router.git" 68 | }, 69 | "author": "Gabriel Moreira", 70 | "license": "MIT", 71 | "bugs": { 72 | "url": "https://github.com/gabrielmoreira/riot-router/issues" 73 | }, 74 | "homepage": "https://github.com/gabrielmoreira/riot-router#readme", 75 | "files": [ 76 | "dist", 77 | "src", 78 | "router.core.js", 79 | "router.js" 80 | ] 81 | } 82 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![npm package](https://img.shields.io/npm/v/riot-router.svg?style=flat-square)](https://www.npmjs.org/package/riot-router) 2 | [![build status](https://img.shields.io/travis/gabrielmoreira/riot-router/master.svg?style=flat-square)](https://travis-ci.org/gabrielmoreira/riot-router) 3 | [![dependency status](https://img.shields.io/david/gabrielmoreira/riot-router.svg?style=flat-square)](https://david-dm.org/gabrielmoreira/riot-router) 4 | 5 | A routing library for Riot. 6 | 7 | Why 8 | --- 9 | 10 | To make it easier to use Riot in SPA applications, I created this url routing library inspired by the React-Router API. 11 | 12 | How? 13 | ---- 14 | 15 | First you create your riot tags: 16 | 17 | ```html 18 | 30 | ``` 31 | 32 | Then you add Riot and Riot-Router to your development page: 33 | 34 | ```html 35 | 36 | 37 | ``` 38 | 39 | Add this special tag in your page: 40 | 41 | ```html 42 | 43 | 44 | or, if your prefer: 45 | 46 |
47 | ``` 48 | 49 | And finally, you declare your routes and initialize your application: 50 | 51 | ```html 52 | 60 | ``` 61 | 62 | Done! 63 | 64 | [See a sample](https://jsbin.com/tihuki) 65 | 66 | [See a todo sample with Redux](https://jsbin.com/jujobe) 67 | 68 | Installation 69 | ------------ 70 | 71 | ```sh 72 | npm install riot-router 73 | ``` 74 | 75 | This library is written with CommonJS modules. If you are using 76 | browserify, webpack, or similar, you can consume it like anything else 77 | installed from npm. 78 | 79 | Advanced examples 80 | ----------------- 81 | 82 | ```js 83 | var Route = Router.Route, 84 | DefaultRoute = Router.DefaultRoute, 85 | NotFoundRoute = Router.NotFoundRoute, 86 | RedirectRoute = Router.RedirectRoute; 87 | 88 | router.routes([ 89 | new DefaultRoute({tag: 'home'}), 90 | new Route({tag: 'about'}), 91 | new Route({tag: 'login'}), 92 | new Route({tag: 'users'}).routes([ 93 | new Route({path:'top', tag: 'users-home', api: {text: 'Select a top user'}}), 94 | new Route({path: '/user/:userId', tag: 'user'}), 95 | new DefaultRoute({tag: 'users-home', api: {text: 'Select a user'}}), 96 | new NotFoundRoute({tag: 'not-found'}) 97 | ]), 98 | new NotFoundRoute({tag: 'not-found'}), 99 | new RedirectRoute({from: 'company', to: 'about'}), 100 | new RedirectRoute({from: 'u', to: 'users/user'}) 101 | ]); 102 | 103 | // Redirect unlogged users to /login page 104 | function securityFilter(request, response, next) { 105 | try { 106 | return next(); 107 | } finally { 108 | if (!window.loggedUser && request.uri !== '/login') { 109 | response.redirectTo = '/login'; 110 | } 111 | } 112 | } 113 | router.use(securityFilter); 114 | 115 | riot.mount('*'); 116 | router.start(); 117 | ``` 118 | -------------------------------------------------------------------------------- /test/router.test.js: -------------------------------------------------------------------------------- 1 | var assert = require('assert'), 2 | helper = require('./support/helper'); 3 | var riot = helper.riot, 4 | router = helper.router, 5 | Router = helper.Router; 6 | 7 | var Route = Router.Route; 8 | var NotFoundRoute = Router.NotFoundRoute; 9 | var DefaultRoute = Router.DefaultRoute; 10 | var Request = Router._.Request; 11 | var Response = Router._.Response; 12 | 13 | 14 | describe('router', function() { 15 | it('can handle riot routes', function() { 16 | router.route(new Route({tag: 'user', path: '/user/:id'})); 17 | router.navigateTo('/user/123'); 18 | assert.equal(router.current.matches[0].tag, 'user'); 19 | assert.equal(router.current.uri, '/user/123'); 20 | }); 21 | }); 22 | 23 | describe('router.Route', function() { 24 | 25 | it('can extract path parameters', function() { 26 | var route = new Route({tag: 'user', path: '/user/:id'}); 27 | var request = new Request('/user/123'); 28 | var response = new Response(request); 29 | assert.ok(route.process(request, response)); 30 | assert.equal(response.size(), 1); 31 | var matcher = response.get(0); 32 | assert.equal(matcher.tag, 'user'); 33 | assert.equal(matcher.route, route); 34 | assert.equal(matcher.params.id, '123'); 35 | }); 36 | 37 | it('can extract encoded path parameters', function() { 38 | var route = new Route({tag: 'user', path: '/user/:name'}); 39 | var request = new Request('/user/Jòsé%26'); 40 | var response = new Response(request); 41 | assert.ok(route.process(request, response)); 42 | assert.equal(response.size(), 1); 43 | var matcher = response.get(0); 44 | assert.equal(matcher.tag, 'user'); 45 | assert.equal(matcher.route, route); 46 | assert.equal(matcher.params.name, 'Jòsé&'); 47 | }); 48 | 49 | it('can handle not found routes', function() { 50 | var route = new Route().routes([ 51 | new Route({tag: 'user', path: '/user/:id'}), 52 | new NotFoundRoute({tag: 'not-found'}) 53 | ]); 54 | var request = new Request('/app/test'); 55 | var response = new Response(request); 56 | assert.ok(route.process(request, response)); 57 | assert.equal(2, response.size()); 58 | var matcher = response.get(1); 59 | assert.equal(matcher.tag, 'not-found'); 60 | }); 61 | 62 | it('can handle default routes', function() { 63 | var route = new Route({path: 'user'}).routes([ 64 | new DefaultRoute({tag: 'user-default'}), 65 | new Route({tag: 'user', path: '/:id'}) 66 | ]); 67 | var request = new Request('/user/'); 68 | var response = new Response(request); 69 | assert.ok(route.process(request, response)); 70 | assert.equal(2, response.size()); 71 | var matcher = response.get(1); 72 | assert.equal(matcher.tag, 'user-default'); 73 | }); 74 | 75 | it('can intercept & redirect route', function(done) { 76 | var userIsLogged = false; 77 | router.use(function(request, response, next) { 78 | try { 79 | return next(); 80 | } finally { 81 | if (request.uri != '/redirected') 82 | response.redirectTo = '/redirected'; 83 | } 84 | }); 85 | router.exec(); 86 | router.routes([ 87 | new Route({tag: 'user', path: '/user/:id', secure: true}), 88 | new Route({tag: 'redirected'}) 89 | ]); 90 | router.on('route:updated', function () { 91 | try { 92 | assert.equal('/redirected', router.current.uri); 93 | assert.equal('redirected', router.current.get(1).tag); 94 | done(); 95 | } catch (e) { 96 | done(e); 97 | } 98 | }); 99 | router.navigateTo('/user/123'); 100 | }); 101 | 102 | it('can extract multiple path parameters', function() { 103 | var route = new Route({tag: 'user', path: '/user/:id/:name'}); 104 | var request = new Request('/user/123/Gabriel'); 105 | var response = new Response(request); 106 | assert.ok(route.process(request, response)); 107 | assert.equal(response.size(), 1); 108 | var matcher = response.get(0); 109 | assert.equal(matcher.tag, 'user'); 110 | assert.equal(matcher.route, route); 111 | assert.equal(matcher.params.id, '123'); 112 | assert.equal(matcher.params.name, 'Gabriel'); 113 | }); 114 | }); 115 | 116 | -------------------------------------------------------------------------------- /examples/redux/app.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 | 5 | 6 |
7 |
8 | 9 |
10 |
11 | 12 |
13 |
14 | 15 |
16 |
17 | 18 | Forgot Password? 19 |
20 |
21 |
22 |
23 | 28 |
29 | 30 | 31 |
32 |
{notification.message}
33 |
34 |
35 |
36 | 50 |
51 |
52 |
53 | 54 |
55 |
56 |
57 | 75 |
76 | 77 | 78 |
79 |
80 |

Hello {email}

81 |
82 |
83 | 84 | this.bindState({ 85 | 'email': 'user.email' 86 | }); 87 |
88 | 89 | 90 |
91 |
92 |

Users

93 |

Listing all users.

94 |
95 |
96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 108 | 109 | 110 |
Name
105 | 106 | {user.first_name} {user.last_name} 107 |
111 | 118 |
119 | 120 | 121 |
122 |

{user.first_name}

123 | 124 |
125 | this.user = {}; 126 | initialize() { 127 | this.actions.user.load(opts.userId); 128 | this.bindState({ 129 | 'user': 'users.usersById[' + opts.userId + ']' 130 | }); 131 | } 132 | this.on('mount', this.initialize); 133 |
-------------------------------------------------------------------------------- /examples/redux/app.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 3 | /** 4 | * App Actions 5 | **/ 6 | function userActions(context) { 7 | var dispatch = context.dispatch; 8 | var getState = context.getState; 9 | var notifyError = context.utils.notifyError; 10 | var post = context.utils.post; 11 | var get = context.utils.get; 12 | var url = context.utils.url; 13 | 14 | function loginWithEmail(email, password) { 15 | post(url.login, { 16 | email: email, 17 | password: password 18 | }).then(function(response) { 19 | dispatch('USER__LOGIN_SUCCESS', {email: email, token: response.token}); 20 | }).catch(function(e) { 21 | dispatch('USER__LOGIN_FAILED', {email: email, cause: e}); 22 | notifyError({message: 'Login Failed', error: e}); 23 | }); 24 | } 25 | 26 | function logout() { 27 | dispatch('USER__LOGOUT'); 28 | } 29 | 30 | function list() { 31 | get(url.list, { 32 | page: 1 33 | }).then(function(response) { 34 | dispatch('USERS__LIST', {users: response.data}); 35 | }) 36 | } 37 | 38 | function load(id) { 39 | var users = getState().users; 40 | if (users.usersById[id]) 41 | return; 42 | list(); 43 | } 44 | 45 | return { 46 | loginWithEmail: loginWithEmail, 47 | logout: logout, 48 | list: list, 49 | load: load 50 | } 51 | } 52 | 53 | /** 54 | * App Reducer 55 | **/ 56 | function userReducer(state, action) { 57 | if (!state) state = {logged: false}; 58 | if (action.type === 'USER__LOGIN_SUCCESS') { 59 | return {logged: true, email: action.payload.email, token: action.payload.token}; 60 | } else if (action.type === 'USER__LOGOUT' || action.type === 'USER__LOGIN_FAILED') { 61 | return {logged: false}; 62 | } 63 | return state; 64 | } 65 | 66 | function usersReducer(state, action) { 67 | if (!state) state = {users: [], usersById: {}}; 68 | switch (action.type) { 69 | case 'USERS__LIST': 70 | return { 71 | users: action.payload.users, 72 | usersById: _.keyBy(action.payload.users, 'id') 73 | }; 74 | } 75 | return state; 76 | } 77 | 78 | var notificationId = 0; 79 | function notificationsReducer(state, action) { 80 | if (!state) state = []; 81 | if (action.type === 'NOTIFICATION__ADD') { 82 | var notification = action.payload; 83 | notification.id = ++notificationId; 84 | return [notification].concat(state); 85 | } else if (action.type === 'NOTIFICATION__DISMISS') { 86 | var id = action.payload.id || action.payload; 87 | return state.filter(function(p) { 88 | return !(id === p.id || action.payload === p); 89 | }); 90 | } 91 | return state; 92 | } 93 | 94 | function loadingReducer(state, action) { 95 | state = state || {count: 0}; 96 | var count = state.count; 97 | switch (action.type) { 98 | case 'LOADING__BEGIN': 99 | count++; 100 | return {active: count > 0, count: count}; 101 | case 'LOADING__END': 102 | count = Math.max(--count, 0); 103 | return {active: count > 0, count: count}; 104 | } 105 | return state; 106 | } 107 | 108 | function routerReducer(state, action) { 109 | state = state || {url: null}; 110 | if (action.type === 'ROUTER__URL') { 111 | state = {url: action.payload.url}; 112 | } 113 | return state; 114 | } 115 | 116 | /** 117 | * App Configuration 118 | **/ 119 | window.app = CreateSimpleApp({ 120 | state: function(context) { 121 | return { 122 | user: JSON.parse(localStorage.getItem('user') || '{}') 123 | } 124 | }, 125 | reducers: function(context) { 126 | return { 127 | user: userReducer, 128 | users: usersReducer, 129 | loading: loadingReducer, 130 | notifications: notificationsReducer, 131 | router: routerReducer 132 | } 133 | }, 134 | actions: function(context) { 135 | return { 136 | user: userActions(context) 137 | } 138 | }, 139 | routes: function(context) { 140 | var Route = Router.Route, 141 | RedirectRoute = Router.RedirectRoute, 142 | DefaultRoute = Router.DefaultRoute; 143 | return [ 144 | new Route({tag: 'app'}).routes([ 145 | new Route({tag: 'users'}), 146 | new Route({tag: 'user', path:'user/:userId'}), 147 | new DefaultRoute({tag: 'home'}) 148 | ]), 149 | new RedirectRoute({from: '', to: 'app'}) 150 | ]; 151 | }, 152 | utils: function(context) { 153 | function appFetch(method, url, data) { 154 | context.dispatch('LOADING__BEGIN', {url: url}); 155 | var req = { 156 | method: method, 157 | headers: { 158 | 'Accept': 'application/json', 159 | 'Content-Type': 'application/json' 160 | } 161 | }; 162 | // add custom backend auth token here... 163 | if (method === 'POST') req.body = JSON.stringify(data); 164 | if (method === 'GET' && data) url = url + (url.indexOf('?') > -1 ? '&' : '?') + $.param(data); 165 | return window.fetch(url, req).then(function(response) { 166 | return response.json().then(function(data) { 167 | context.dispatch('LOADING__END', {url: url}); 168 | if (response.status === 200) { 169 | return data; 170 | } else { 171 | var error = new Error(response.statusText); 172 | error.response = response; 173 | error.data = data; 174 | throw error; 175 | } 176 | }); 177 | }); 178 | } 179 | 180 | function appNotify(type, notification) { 181 | notification.type = type; 182 | return context.dispatch('NOTIFICATION__ADD', notification); 183 | } 184 | 185 | return { 186 | // ajax 187 | url: { 188 | login: 'https://reqres.in/api/login', 189 | list: 'https://reqres.in/api/users' 190 | }, 191 | post: appFetch.bind(null, 'POST'), 192 | get: appFetch.bind(null, 'GET'), 193 | 194 | // notifications 195 | notifyError: appNotify.bind(null, 'danger'), 196 | notifySuccess: appNotify.bind(null, 'success'), 197 | notifyAlert: appNotify.bind(null, 'warning'), 198 | notifyInfo: appNotify.bind(null, 'info'), 199 | dismiss: function(notification) { 200 | context.dispatch('NOTIFICATION__DISMISS', notification); 201 | } 202 | }; 203 | } 204 | }); 205 | 206 | /** 207 | * Custom Listeners 208 | **/ 209 | app.on('USER__LOGIN_SUCCESS USER__LOGOUT', function() { 210 | var state = app.getState(); 211 | if (state.user.logged) { 212 | try { 213 | localStorage.setItem('user', JSON.stringify(state.user)); 214 | } catch (e) {}; 215 | 216 | } else { 217 | localStorage.removeItem('user'); 218 | } 219 | router.navigateTo('/app'); 220 | }); 221 | 222 | router.on('route:updated', function() { 223 | app.dispatch('ROUTER__URL', {url: router.current.uri}); 224 | }); 225 | 226 | app.store.subscribe(function() { 227 | var state = app.getState(); 228 | if (state.router.url !== null 229 | && state.router.url !== router.current.uri) { 230 | router.navigateTo(state.router.url); 231 | } 232 | }); 233 | 234 | })(); 235 | -------------------------------------------------------------------------------- /examples/example-01.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Riot App Example 01 6 | 7 | 8 | 32 | 33 | 34 | 35 | 36 | 39 | 219 | 220 | 223 | 242 | 243 | 244 | 245 | 246 | 249 | 303 | 304 | 305 | -------------------------------------------------------------------------------- /dist/router.core.min.js: -------------------------------------------------------------------------------- 1 | !function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e(require("riot")):"function"==typeof define&&define.amd?define(["riot"],e):"object"==typeof exports?exports.Router=e(require("riot")):t.Router=e(t.riot)}(this,function(t){return function(t){function e(n){if(r[n])return r[n].exports;var o=r[n]={exports:{},id:n,loaded:!1};return t[n].call(o.exports,o,o.exports,e),o.loaded=!0,o.exports}var r={};return e.m=t,e.c=r,e.p="/dist/",e(0)}([function(t,e,r){var n,o,i;!function(u,s){o=[t,r(4)],n=s,i="function"==typeof n?n.apply(e,o):n,!(void 0!==i&&(t.exports=i))}(this,function(t,e){"use strict";t.exports=e})},function(e,r){e.exports=t},,,function(t,e,r){var n,o,i;(function(u){!function(u,s){o=[t,r(1),r(5)],n=s,i="function"==typeof n?n.apply(e,o):n,!(void 0!==i&&(t.exports=i))}(this,function(t,e,r){"use strict";function n(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function o(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}function i(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function s(t){e.tag("route","","","",function(n){this.calculateLevel=function(t){var e=0;return t.parent&&(e+=this.calculateLevel(t.parent)),t.opts.__router_level&&(e+=t.opts.__router_level),t.__router_tag&&(e+=1),e}.bind(this),this.normalizeTag=function(t,e,r){var n=t(e,r);return"string"==typeof n?t=n:(t=n.tag||t,e=n.api||e),[t,e,r]},this.unmountTag=function(){this.instance&&this.instance.unmount(!0)},this.mountTag=function(t,r,n){if("function"==typeof t){var o=this.normalizeTag(t,r,n),i=h(o,3);t=i[0],r=i[1],n=i[2]}if(this.canUpdate(t,r,n))this.instance.update(r);else if(this.unmountTag(),t){this.root.replaceChild(document.createElement(t),this.root.children[0]);try{this.instance=e.mount(this.root.children[0],t,r)[0]}catch(e){return void l("Error when mounting tag '"+t+"'.",e)}this.instanceTag=t,this.instanceApi=r}},this.canUpdate=function(e,r,o){return!!((t.config.updatable||n.updatable||o.updatable)&&this.instance&&this.instance.isMounted&&this.instanceTag===e)},this.updateRoute=function(){var e={tag:null};if(t&&t.current){var o=t.current;if(this.level<=o.size()){var i=o.get(this.level);if(i){var u=i.params||{},s=o.query||{},a=r(!0,{},n,s,i.api,u,{__router_level:this.level,query:s});e={tag:i.tag,api:a,updatable:i.route.updatable}}}}e.tag?this.mountTag(e.tag,e.api,e):this.unmountTag()}.bind(this),this.__router_tag="route",this.level=this.calculateLevel(this),t.on("route:updated",this.updateRoute),this.on("unmount",function(){t.off("route:updated",this.updateRoute),this.unmountTag()}.bind(this)),this.on("mount",this.updateRoute)})}function a(){var t=e.route||window&&window.route||u&&u.route;return t}function c(t){var e=new y;return e.configure(r(!0,{updatable:!0,route:a(),base:"#",parser:function(t){var e=t.split("?"),r=e[0].split("/"),n=e[1],o={};return n&&n.split("&").forEach(function(t){var e=t.split("=");o[e[0]]=e[1]}),r.push(o),r}},t)),s(e),y.instance||(y.instance=e),e}var h=function(){function t(t,e){var r=[],n=!0,o=!1,i=void 0;try{for(var u,s=t[Symbol.iterator]();!(n=(u=s.next()).done)&&(r.push(u.value),!e||r.length!==e);n=!0);}catch(t){o=!0,i=t}finally{try{!n&&s.return&&s.return()}finally{if(o)throw i}}return r}return function(e,r){if(Array.isArray(e))return e;if(Symbol.iterator in Object(e))return t(e,r);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}(),f=function t(e,r,n){null===e&&(e=Function.prototype);var o=Object.getOwnPropertyDescriptor(e,r);if(void 0===o){var i=Object.getPrototypeOf(e);return null===i?void 0:t(i,r,n)}if("value"in o)return o.value;var u=o.get;if(void 0!==u)return u.call(n)},p=function(){function t(t,e){for(var r=0;r-1)throw new Error("Cyclic redirection to "+t+". Stack = "+this.redirectStack);this.redirectStack.push(t)}}]),t}(),d=function(){function t(){i(this,t)}return p(t,[{key:"matches",value:function(t){return!1}},{key:"process",value:function(t,e){var r=this.matches(t);return r?this.routeMatch(t,e,r):this.routeMiss(t,e)}},{key:"routeMatch",value:function(t,e,r){return e.add(r),!0}},{key:"routeMiss",value:function(t,e){return!1}},{key:"processRoutes",value:function(t,e,r){if(r&&r.length){for(var n=r.length,o=0;o1&&l("Can't use more than one NotFoundRoute per route. --> "+this.getPath()),r.length>1&&l("Can't use more than one DefaultRoute per route. --> "+this.getPath()),this._routes=[].concat(e).concat(o).concat(r).concat(n),this}},{key:"matches",value:function(t){var e=this.regex.exec(t.uri);if(e){var r={};for(var n in this.pathParameterNames)if(this.pathParameterNames.hasOwnProperty(n)){var o=this.pathParameterNames[n];r[o]=decodeURIComponent(e[parseInt(n,10)+1])}return{route:this,tag:this.tag,api:this.api,found:e[0],params:r}}return!1}},{key:"routeMatch",value:function(t,r,n){var o=f(e.prototype.__proto__||Object.getPrototypeOf(e.prototype),"routeMatch",this).call(this,t,r,n);return this.processRoutes(t,r,n),o}},{key:"processRoutes",value:function(t,r,n){return f(e.prototype.__proto__||Object.getPrototypeOf(e.prototype),"processRoutes",this).call(this,this.createRequest(t,n),r,this._routes)}},{key:"getPath",value:function(){return this.name||this.path||("string"==typeof this.tag?this.tag:"")}}]),e}(d),m=function(t){function e(){return i(this,e),n(this,(e.__proto__||Object.getPrototypeOf(e)).apply(this,arguments))}return o(e,t),e}(g),b=function t(e,r){i(this,t),this.request=e,this.matcher=r,this.uri=this.request.uri.substring(r.found.length),this.parentUri=this.request.uri.substring(0,r.found.length),this.query=this.request.query},_=function(t){function e(t){i(this,e);var r=n(this,(e.__proto__||Object.getPrototypeOf(e)).call(this,t));return t=t||{},r.tag=t.tag,r.api=t.api,r}return o(e,t),p(e,[{key:"matches",value:function(t){return{route:this,tag:this.tag,api:this.api,found:t.uri}}}]),e}(d),k=function(t){function e(t){i(this,e);var r=n(this,(e.__proto__||Object.getPrototypeOf(e)).call(this,t));return t=t||{},r.from=t.from,r.to=t.to,r.pattern="(^/?)"+r.from+"(/|$)",r.regex=new RegExp(r.pattern),r}return o(e,t),p(e,[{key:"process",value:function(t,e){var r=t.uri.replace(this.regex,"$1"+this.to+"$2");if(r!==t.uri){var n=t.parentUri||"";return e.redirectTo=n+r,!0}}}]),e}(d),R=function(t){function e(t){i(this,e);var r=n(this,(e.__proto__||Object.getPrototypeOf(e)).call(this,t));return t=t||{},r.tag=t.tag,r.api=t.api,r}return o(e,t),p(e,[{key:"matches",value:function(t){var e=t.uri.trim();if("/"===e||""===e)return{route:this,tag:this.tag,api:this.api,found:e}}}]),e}(d),O=function t(e,r){i(this,t),this.uri=e,this.query=r},x=function(){function t(e){i(this,t),this.uri=e.uri,this.matches=[],this.params={},this.query=e.query}return p(t,[{key:"add",value:function(t){this.matches.push(t);var e=t.params;if(e)for(var r in e)e.hasOwnProperty(r)&&(this.params[r]=e[r])}},{key:"get",value:function(t){return this.matches[t]}},{key:"size",value:function(){return this.matches.length}},{key:"isEmpty",value:function(){return this.matches.length}}]),t}();y.create=c,y.Route=g,y.DefaultRoute=R,y.RedirectRoute=k,y.NotFoundRoute=_,y._={Response:x,Request:O},t.exports=y})}).call(e,function(){return this}())},function(t,e){"use strict";var r=Object.prototype.hasOwnProperty,n=Object.prototype.toString,o=function(t){return"function"==typeof Array.isArray?Array.isArray(t):"[object Array]"===n.call(t)},i=function(t){if(!t||"[object Object]"!==n.call(t))return!1;var e=r.call(t,"constructor"),o=t.constructor&&t.constructor.prototype&&r.call(t.constructor.prototype,"isPrototypeOf");if(t.constructor&&!e&&!o)return!1;var i;for(i in t);return"undefined"==typeof i||r.call(t,i)};t.exports=function t(){var e,r,n,u,s,a,c=arguments[0],h=1,f=arguments.length,p=!1;for("boolean"==typeof c?(p=c,c=arguments[1]||{},h=2):("object"!=typeof c&&"function"!=typeof c||null==c)&&(c={});h","","",function(n){this.calculateLevel=function(t){var e=0;return t.parent&&(e+=this.calculateLevel(t.parent)),t.opts.__router_level&&(e+=t.opts.__router_level),t.__router_tag&&(e+=1),e}.bind(this),this.normalizeTag=function(t,e,r){var n=t(e,r);return"string"==typeof n?t=n:(t=n.tag||t,e=n.api||e),[t,e,r]},this.unmountTag=function(){this.instance&&this.instance.unmount(!0)},this.mountTag=function(t,r,n){if("function"==typeof t){var i=this.normalizeTag(t,r,n),o=f(i,3);t=o[0],r=o[1],n=o[2]}if(this.canUpdate(t,r,n))this.instance.update(r);else if(this.unmountTag(),t){this.root.replaceChild(document.createElement(t),this.root.children[0]);try{this.instance=e.mount(this.root.children[0],t,r)[0]}catch(e){return void l("Error when mounting tag '"+t+"'.",e)}this.instanceTag=t,this.instanceApi=r}},this.canUpdate=function(e,r,i){return!!((t.config.updatable||n.updatable||i.updatable)&&this.instance&&this.instance.isMounted&&this.instanceTag===e)},this.updateRoute=function(){var e={tag:null};if(t&&t.current){var i=t.current;if(this.level<=i.size()){var o=i.get(this.level);if(o){var u=o.params||{},s=i.query||{},a=r(!0,{},n,s,o.api,u,{__router_level:this.level,query:s});e={tag:o.tag,api:a,updatable:o.route.updatable}}}}e.tag?this.mountTag(e.tag,e.api,e):this.unmountTag()}.bind(this),this.__router_tag="route",this.level=this.calculateLevel(this),t.on("route:updated",this.updateRoute),this.on("unmount",function(){t.off("route:updated",this.updateRoute),this.unmountTag()}.bind(this)),this.on("mount",this.updateRoute)})}function a(){var t=e.route||window&&window.route||u&&u.route;return t}function c(t){var e=new d;return e.configure(r(!0,{updatable:!0,route:a(),base:"#",parser:function(t){var e=t.split("?"),r=e[0].split("/"),n=e[1],i={};return n&&n.split("&").forEach(function(t){var e=t.split("=");i[e[0]]=e[1]}),r.push(i),r}},t)),s(e),d.instance||(d.instance=e),e}var f=function(){function t(t,e){var r=[],n=!0,i=!1,o=void 0;try{for(var u,s=t[Symbol.iterator]();!(n=(u=s.next()).done)&&(r.push(u.value),!e||r.length!==e);n=!0);}catch(t){i=!0,o=t}finally{try{!n&&s.return&&s.return()}finally{if(i)throw o}}return r}return function(e,r){if(Array.isArray(e))return e;if(Symbol.iterator in Object(e))return t(e,r);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}(),h=function t(e,r,n){null===e&&(e=Function.prototype);var i=Object.getOwnPropertyDescriptor(e,r);if(void 0===i){var o=Object.getPrototypeOf(e);return null===o?void 0:t(o,r,n)}if("value"in i)return i.value;var u=i.get;if(void 0!==u)return u.call(n)},p=function(){function t(t,e){for(var r=0;r-1)throw new Error("Cyclic redirection to "+t+". Stack = "+this.redirectStack);this.redirectStack.push(t)}}]),t}(),v=function(){function t(){o(this,t)}return p(t,[{key:"matches",value:function(t){return!1}},{key:"process",value:function(t,e){var r=this.matches(t);return r?this.routeMatch(t,e,r):this.routeMiss(t,e)}},{key:"routeMatch",value:function(t,e,r){return e.add(r),!0}},{key:"routeMiss",value:function(t,e){return!1}},{key:"processRoutes",value:function(t,e,r){if(r&&r.length){for(var n=r.length,i=0;i1&&l("Can't use more than one NotFoundRoute per route. --> "+this.getPath()),r.length>1&&l("Can't use more than one DefaultRoute per route. --> "+this.getPath()),this._routes=[].concat(e).concat(i).concat(r).concat(n),this}},{key:"matches",value:function(t){var e=this.regex.exec(t.uri);if(e){var r={};for(var n in this.pathParameterNames)if(this.pathParameterNames.hasOwnProperty(n)){var i=this.pathParameterNames[n];r[i]=decodeURIComponent(e[parseInt(n,10)+1])}return{route:this,tag:this.tag,api:this.api,found:e[0],params:r}}return!1}},{key:"routeMatch",value:function(t,r,n){var i=h(e.prototype.__proto__||Object.getPrototypeOf(e.prototype),"routeMatch",this).call(this,t,r,n);return this.processRoutes(t,r,n),i}},{key:"processRoutes",value:function(t,r,n){return h(e.prototype.__proto__||Object.getPrototypeOf(e.prototype),"processRoutes",this).call(this,this.createRequest(t,n),r,this._routes)}},{key:"getPath",value:function(){return this.name||this.path||("string"==typeof this.tag?this.tag:"")}}]),e}(v),m=function(t){function e(){return o(this,e),n(this,(e.__proto__||Object.getPrototypeOf(e)).apply(this,arguments))}return i(e,t),e}(g),b=function t(e,r){o(this,t),this.request=e,this.matcher=r,this.uri=this.request.uri.substring(r.found.length),this.parentUri=this.request.uri.substring(0,r.found.length),this.query=this.request.query},w=function(t){function e(t){o(this,e);var r=n(this,(e.__proto__||Object.getPrototypeOf(e)).call(this,t));return t=t||{},r.tag=t.tag,r.api=t.api,r}return i(e,t),p(e,[{key:"matches",value:function(t){return{route:this,tag:this.tag,api:this.api,found:t.uri}}}]),e}(v),_=function(t){function e(t){o(this,e);var r=n(this,(e.__proto__||Object.getPrototypeOf(e)).call(this,t));return t=t||{},r.from=t.from,r.to=t.to,r.pattern="(^/?)"+r.from+"(/|$)",r.regex=new RegExp(r.pattern),r}return i(e,t),p(e,[{key:"process",value:function(t,e){var r=t.uri.replace(this.regex,"$1"+this.to+"$2");if(r!==t.uri){var n=t.parentUri||"";return e.redirectTo=n+r,!0}}}]),e}(v),x=function(t){function e(t){o(this,e);var r=n(this,(e.__proto__||Object.getPrototypeOf(e)).call(this,t));return t=t||{},r.tag=t.tag,r.api=t.api,r}return i(e,t),p(e,[{key:"matches",value:function(t){var e=t.uri.trim();if("/"===e||""===e)return{route:this,tag:this.tag,api:this.api,found:e}}}]),e}(v),k=function t(e,r){o(this,t),this.uri=e,this.query=r},O=function(){function t(e){o(this,t),this.uri=e.uri,this.matches=[],this.params={},this.query=e.query}return p(t,[{key:"add",value:function(t){this.matches.push(t);var e=t.params;if(e)for(var r in e)e.hasOwnProperty(r)&&(this.params[r]=e[r])}},{key:"get",value:function(t){return this.matches[t]}},{key:"size",value:function(){return this.matches.length}},{key:"isEmpty",value:function(){return this.matches.length}}]),t}();d.create=c,d.Route=g,d.DefaultRoute=x,d.RedirectRoute=_,d.NotFoundRoute=w,d._={Response:O,Request:k},t.exports=d})}).call(e,function(){return this}())},function(t,e){"use strict";var r=Object.prototype.hasOwnProperty,n=Object.prototype.toString,i=function(t){return"function"==typeof Array.isArray?Array.isArray(t):"[object Array]"===n.call(t)},o=function(t){if(!t||"[object Object]"!==n.call(t))return!1;var e=r.call(t,"constructor"),i=t.constructor&&t.constructor.prototype&&r.call(t.constructor.prototype,"isPrototypeOf");if(t.constructor&&!e&&!i)return!1;var o;for(o in t);return"undefined"==typeof o||r.call(t,o)};t.exports=function t(){var e,r,n,u,s,a,c=arguments[0],f=1,h=arguments.length,p=!1;for("boolean"==typeof c?(p=c,c=arguments[1]||{},f=2):("object"!=typeof c&&"function"!=typeof c||null==c)&&(c={});f -1) 133 | throw new Error("Cyclic redirection to " + uri + ". Stack = " + this.redirectStack); 134 | this.redirectStack.push(uri); 135 | } 136 | 137 | } 138 | 139 | class Handler { 140 | constructor() {} 141 | 142 | matches(request) { 143 | return false; 144 | } 145 | 146 | process(request, response) { 147 | var matcher = this.matches(request); 148 | if (!matcher) return this.routeMiss(request, response); 149 | return this.routeMatch(request, response, matcher); 150 | } 151 | 152 | routeMatch(request, response, matcher) { 153 | response.add(matcher); 154 | return true; 155 | } 156 | 157 | routeMiss(request, response) { 158 | return false; 159 | } 160 | 161 | processRoutes(request, response, routes) { 162 | if (routes && routes.length) { 163 | var t = routes.length; 164 | for (var i = 0; i < t; i++) { 165 | var route = routes[i]; 166 | if (route.process(request, response)) 167 | return true; 168 | } 169 | return false; 170 | } 171 | } 172 | 173 | createRequest(request, matcher) { 174 | return new ChildRequest(request, matcher); 175 | } 176 | } 177 | 178 | class Route extends Handler { 179 | constructor(options) { 180 | super(options); 181 | options = options || {}; 182 | this.tag = options.tag; 183 | this.api = options.api; 184 | this.path = options.path; 185 | this.name = options.name; 186 | this.updatable = options.updatable; 187 | this.pathParameterNames = []; 188 | var path = this.getPath().replace(/^\//, ""); 189 | this.pattern = "^/?" + path.replace(/:([^/]+)/g, function (ignored, group) { 190 | this.pathParameterNames.push(group); 191 | return "([^/]+)"; 192 | }.bind(this)) + "(:?/|$)"; 193 | this.regex = new RegExp(this.pattern); 194 | } 195 | 196 | routes(routes) { 197 | var redirectRoutes = routes.filter(function (r) { 198 | return r instanceof RedirectRoute; 199 | }); 200 | var defaultRoutes = routes.filter(function (r) { 201 | return r instanceof DefaultRoute; 202 | }); 203 | var notFoundRoutes = routes.filter(function (r) { 204 | return r instanceof NotFoundRoute; 205 | }); 206 | var otherRoutes = routes.filter(function (r) { 207 | return redirectRoutes.indexOf(r) === -1 && 208 | defaultRoutes.indexOf(r) === -1 && 209 | notFoundRoutes.indexOf(r) === -1; 210 | }); 211 | if (notFoundRoutes.length > 1) error("Can't use more than one NotFoundRoute per route. --> " + this.getPath()); 212 | if (defaultRoutes.length > 1) error("Can't use more than one DefaultRoute per route. --> " + this.getPath()); 213 | this._routes = [].concat(redirectRoutes).concat(otherRoutes).concat(defaultRoutes).concat(notFoundRoutes); 214 | return this; 215 | } 216 | 217 | matches(request) { 218 | var matcher = this.regex.exec(request.uri); 219 | if (matcher) { 220 | var params = {}; 221 | for (var i in this.pathParameterNames) { 222 | if (this.pathParameterNames.hasOwnProperty(i)) { 223 | var name = this.pathParameterNames[i]; 224 | params[name] = decodeURIComponent(matcher[parseInt(i, 10) + 1]); 225 | } 226 | } 227 | return { 228 | route: this, 229 | tag: this.tag, 230 | api: this.api, 231 | found: matcher[0], 232 | params: params 233 | }; 234 | } 235 | return false; 236 | } 237 | 238 | routeMatch(request, response, matcher) { 239 | var matches = super.routeMatch(request, response, matcher); 240 | this.processRoutes(request, response, matcher); 241 | return matches; 242 | } 243 | 244 | processRoutes(request, response, matcher) { 245 | return super.processRoutes(this.createRequest(request, matcher), response, this._routes); 246 | } 247 | 248 | getPath() { 249 | return this.name || this.path || (typeof this.tag === 'string' ? this.tag : ''); 250 | } 251 | } 252 | 253 | class InitialRoute extends Route { 254 | 255 | } 256 | 257 | class ChildRequest { 258 | constructor(request, matcher) { 259 | this.request = request; 260 | this.matcher = matcher; 261 | this.uri = this.request.uri.substring(matcher.found.length); 262 | this.parentUri = this.request.uri.substring(0, matcher.found.length); 263 | this.query = this.request.query; 264 | } 265 | } 266 | 267 | class NotFoundRoute extends Handler { 268 | constructor(options) { 269 | super(options); 270 | options = options || {}; 271 | this.tag = options.tag; 272 | this.api = options.api; 273 | } 274 | matches(request) { 275 | return { 276 | route: this, 277 | tag: this.tag, 278 | api: this.api, 279 | found: request.uri 280 | }; 281 | } 282 | } 283 | 284 | class RedirectRoute extends Handler { 285 | constructor(options) { 286 | super(options); 287 | options = options || {}; 288 | this.from = options.from; 289 | this.to = options.to; 290 | this.pattern = "(^/?)" + this.from + "(/|$)"; 291 | this.regex = new RegExp(this.pattern); 292 | } 293 | 294 | process(request, response) { 295 | var uri = request.uri.replace(this.regex, "$1" + this.to + "$2"); 296 | if (uri !== request.uri) { 297 | var parent = request.parentUri || ""; 298 | response.redirectTo = parent + uri; 299 | return true; 300 | } 301 | } 302 | 303 | } 304 | 305 | class DefaultRoute extends Handler { 306 | constructor(options) { 307 | super(options); 308 | options = options || {}; 309 | this.tag = options.tag; 310 | this.api = options.api; 311 | } 312 | matches(request) { 313 | var uri = request.uri.trim(); 314 | if (uri === "/" || uri === "") 315 | return { 316 | route: this, 317 | tag: this.tag, 318 | api: this.api, 319 | found: uri 320 | }; 321 | } 322 | } 323 | 324 | class Request { 325 | constructor(uri, query) { 326 | this.uri = uri; 327 | this.query = query; 328 | } 329 | } 330 | 331 | class Response { 332 | constructor(request) { 333 | this.uri = request.uri; 334 | this.matches = []; 335 | this.params = {}; 336 | this.query = request.query; 337 | } 338 | add(matcher) { 339 | this.matches.push(matcher); 340 | var params = matcher.params; 341 | if (params) { 342 | for (var key in params) { 343 | if (params.hasOwnProperty(key)) { 344 | this.params[key] = params[key]; 345 | } 346 | } 347 | } 348 | } 349 | 350 | get(index) { 351 | return this.matches[index]; 352 | } 353 | 354 | size() { 355 | return this.matches.length; 356 | } 357 | 358 | isEmpty() { 359 | return this.matches.length; 360 | } 361 | 362 | } 363 | 364 | function registerTag(router) { 365 | riot.tag('route', '', '', '', function (opts) { 366 | this.calculateLevel = function (target) { 367 | var level = 0; 368 | if (target.parent) level += this.calculateLevel(target.parent); 369 | if (target.opts.__router_level) level += target.opts.__router_level; 370 | if (target.__router_tag) level += 1; 371 | return level; 372 | }.bind(this); 373 | 374 | this.normalizeTag = function (tag, api, options) { 375 | var result = tag(api, options); 376 | if (typeof result === 'string') { 377 | tag = result; 378 | } else { 379 | tag = result.tag || tag; 380 | api = result.api || api; 381 | } 382 | return [tag, api, options]; 383 | } 384 | 385 | this.unmountTag = function () { 386 | if (this.instance) 387 | this.instance.unmount(true); 388 | } 389 | 390 | this.mountTag = function (tag, api, options) { 391 | if (typeof tag === 'function') { 392 | [tag, api, options] = this.normalizeTag(tag, api, options); 393 | } 394 | if (this.canUpdate(tag, api, options)) { 395 | this.instance.update(api); 396 | } else { 397 | this.unmountTag(); 398 | if (tag) { 399 | this.root.replaceChild(document.createElement(tag), this.root.children[0]); 400 | try { 401 | this.instance = riot.mount(this.root.children[0], tag, api)[0]; 402 | } catch (e) { 403 | error("Error when mounting tag '" + tag + "'.", e); 404 | return; 405 | } 406 | this.instanceTag = tag; 407 | this.instanceApi = api; 408 | } 409 | } 410 | } 411 | 412 | this.canUpdate = function (tag, api, options) { 413 | if ((!router.config.updatable && !opts.updatable && !options.updatable) || 414 | !this.instance || 415 | !this.instance.isMounted || 416 | this.instanceTag !== tag) 417 | return false; 418 | return true; 419 | } 420 | 421 | this.updateRoute = function () { 422 | var mount = { 423 | tag: null 424 | }; 425 | if (router && router.current) { 426 | var response = router.current; 427 | if (this.level <= response.size()) { 428 | var matcher = response.get(this.level); 429 | if (matcher) { 430 | var params = matcher.params || {}; 431 | var query = response.query || {}; 432 | var api = extend(true, {}, opts, query, matcher.api, params, { 433 | __router_level: this.level, 434 | query: query 435 | }); 436 | mount = { 437 | tag: matcher.tag, 438 | api: api, 439 | updatable: matcher.route.updatable 440 | }; 441 | } 442 | } 443 | } 444 | if (mount.tag) 445 | this.mountTag(mount.tag, mount.api, mount); 446 | else 447 | this.unmountTag(); 448 | }.bind(this); 449 | 450 | this.__router_tag = 'route'; 451 | this.level = this.calculateLevel(this); 452 | router.on('route:updated', this.updateRoute); 453 | this.on('unmount', function () { 454 | router.off('route:updated', this.updateRoute); 455 | this.unmountTag(); 456 | }.bind(this)); 457 | this.on('mount', this.updateRoute); 458 | }); 459 | } 460 | 461 | function detectRoute() { 462 | var route = riot.route || 463 | (window && window.route) || 464 | (global && global.route); 465 | return route; 466 | } 467 | 468 | function create(config) { 469 | var router = new Router(); 470 | router.configure(extend(true, { 471 | updatable: true, 472 | route: detectRoute(), 473 | base: '#', 474 | parser: function customRiotParser(path) { 475 | var raw = path.split('?'), 476 | uri = raw[0].split('/'), 477 | query = raw[1], 478 | params = {} 479 | if (query) { 480 | query.split('&').forEach(function (v) { 481 | var c = v.split('=') 482 | params[c[0]] = c[1] 483 | }) 484 | } 485 | uri.push(params) 486 | return uri 487 | } 488 | }, config)); 489 | registerTag(router); 490 | if (!Router.instance) Router.instance = router; 491 | return router; 492 | } 493 | Router.create = create; 494 | Router.Route = Route; 495 | Router.DefaultRoute = DefaultRoute; 496 | Router.RedirectRoute = RedirectRoute; 497 | Router.NotFoundRoute = NotFoundRoute; 498 | Router._ = { 499 | Response: Response, 500 | Request: Request 501 | }; 502 | module.exports = Router; 503 | -------------------------------------------------------------------------------- /dist/router.core.js: -------------------------------------------------------------------------------- 1 | (function webpackUniversalModuleDefinition(root, factory) { 2 | if(typeof exports === 'object' && typeof module === 'object') 3 | module.exports = factory(require("riot")); 4 | else if(typeof define === 'function' && define.amd) 5 | define(["riot"], factory); 6 | else if(typeof exports === 'object') 7 | exports["Router"] = factory(require("riot")); 8 | else 9 | root["Router"] = factory(root["riot"]); 10 | })(this, function(__WEBPACK_EXTERNAL_MODULE_1__) { 11 | return /******/ (function(modules) { // webpackBootstrap 12 | /******/ // The module cache 13 | /******/ var installedModules = {}; 14 | /******/ 15 | /******/ // The require function 16 | /******/ function __webpack_require__(moduleId) { 17 | /******/ 18 | /******/ // Check if module is in cache 19 | /******/ if(installedModules[moduleId]) 20 | /******/ return installedModules[moduleId].exports; 21 | /******/ 22 | /******/ // Create a new module (and put it into the cache) 23 | /******/ var module = installedModules[moduleId] = { 24 | /******/ exports: {}, 25 | /******/ id: moduleId, 26 | /******/ loaded: false 27 | /******/ }; 28 | /******/ 29 | /******/ // Execute the module function 30 | /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 31 | /******/ 32 | /******/ // Flag the module as loaded 33 | /******/ module.loaded = true; 34 | /******/ 35 | /******/ // Return the exports of the module 36 | /******/ return module.exports; 37 | /******/ } 38 | /******/ 39 | /******/ 40 | /******/ // expose the modules object (__webpack_modules__) 41 | /******/ __webpack_require__.m = modules; 42 | /******/ 43 | /******/ // expose the module cache 44 | /******/ __webpack_require__.c = installedModules; 45 | /******/ 46 | /******/ // __webpack_public_path__ 47 | /******/ __webpack_require__.p = "/dist/"; 48 | /******/ 49 | /******/ // Load entry module and return exports 50 | /******/ return __webpack_require__(0); 51 | /******/ }) 52 | /************************************************************************/ 53 | /******/ ([ 54 | /* 0 */ 55 | /***/ function(module, exports, __webpack_require__) { 56 | 57 | var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function (global, factory) { 58 | if (true) { 59 | !(__WEBPACK_AMD_DEFINE_ARRAY__ = [module, __webpack_require__(4)], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); 60 | } else if (typeof exports !== "undefined") { 61 | factory(module, require('./src/router.js')); 62 | } else { 63 | var mod = { 64 | exports: {} 65 | }; 66 | factory(mod, global.router); 67 | global.routerCore = mod.exports; 68 | } 69 | })(this, function (module, Router) { 70 | 'use strict'; 71 | 72 | module.exports = Router; 73 | }); 74 | 75 | /***/ }, 76 | /* 1 */ 77 | /***/ function(module, exports) { 78 | 79 | module.exports = __WEBPACK_EXTERNAL_MODULE_1__; 80 | 81 | /***/ }, 82 | /* 2 */, 83 | /* 3 */, 84 | /* 4 */ 85 | /***/ function(module, exports, __webpack_require__) { 86 | 87 | var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/* WEBPACK VAR INJECTION */(function(global) {(function (global, factory) { 88 | if (true) { 89 | !(__WEBPACK_AMD_DEFINE_ARRAY__ = [module, __webpack_require__(1), __webpack_require__(5)], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); 90 | } else if (typeof exports !== "undefined") { 91 | factory(module, require('riot'), require('extend')); 92 | } else { 93 | var mod = { 94 | exports: {} 95 | }; 96 | factory(mod, global.riot, global.extend); 97 | global.router = mod.exports; 98 | } 99 | })(this, function (module, riot, extend) { 100 | 'use strict'; 101 | 102 | var _slicedToArray = function () { 103 | function sliceIterator(arr, i) { 104 | var _arr = []; 105 | var _n = true; 106 | var _d = false; 107 | var _e = undefined; 108 | 109 | try { 110 | for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { 111 | _arr.push(_s.value); 112 | 113 | if (i && _arr.length === i) break; 114 | } 115 | } catch (err) { 116 | _d = true; 117 | _e = err; 118 | } finally { 119 | try { 120 | if (!_n && _i["return"]) _i["return"](); 121 | } finally { 122 | if (_d) throw _e; 123 | } 124 | } 125 | 126 | return _arr; 127 | } 128 | 129 | return function (arr, i) { 130 | if (Array.isArray(arr)) { 131 | return arr; 132 | } else if (Symbol.iterator in Object(arr)) { 133 | return sliceIterator(arr, i); 134 | } else { 135 | throw new TypeError("Invalid attempt to destructure non-iterable instance"); 136 | } 137 | }; 138 | }(); 139 | 140 | function _possibleConstructorReturn(self, call) { 141 | if (!self) { 142 | throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); 143 | } 144 | 145 | return call && (typeof call === "object" || typeof call === "function") ? call : self; 146 | } 147 | 148 | var _get = function get(object, property, receiver) { 149 | if (object === null) object = Function.prototype; 150 | var desc = Object.getOwnPropertyDescriptor(object, property); 151 | 152 | if (desc === undefined) { 153 | var parent = Object.getPrototypeOf(object); 154 | 155 | if (parent === null) { 156 | return undefined; 157 | } else { 158 | return get(parent, property, receiver); 159 | } 160 | } else if ("value" in desc) { 161 | return desc.value; 162 | } else { 163 | var getter = desc.get; 164 | 165 | if (getter === undefined) { 166 | return undefined; 167 | } 168 | 169 | return getter.call(receiver); 170 | } 171 | }; 172 | 173 | function _inherits(subClass, superClass) { 174 | if (typeof superClass !== "function" && superClass !== null) { 175 | throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); 176 | } 177 | 178 | subClass.prototype = Object.create(superClass && superClass.prototype, { 179 | constructor: { 180 | value: subClass, 181 | enumerable: false, 182 | writable: true, 183 | configurable: true 184 | } 185 | }); 186 | if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; 187 | } 188 | 189 | function _classCallCheck(instance, Constructor) { 190 | if (!(instance instanceof Constructor)) { 191 | throw new TypeError("Cannot call a class as a function"); 192 | } 193 | } 194 | 195 | var _createClass = function () { 196 | function defineProperties(target, props) { 197 | for (var i = 0; i < props.length; i++) { 198 | var descriptor = props[i]; 199 | descriptor.enumerable = descriptor.enumerable || false; 200 | descriptor.configurable = true; 201 | if ("value" in descriptor) descriptor.writable = true; 202 | Object.defineProperty(target, descriptor.key, descriptor); 203 | } 204 | } 205 | 206 | return function (Constructor, protoProps, staticProps) { 207 | if (protoProps) defineProperties(Constructor.prototype, protoProps); 208 | if (staticProps) defineProperties(Constructor, staticProps); 209 | return Constructor; 210 | }; 211 | }(); 212 | 213 | var error = console && console.error || function () {}; 214 | 215 | var Router = function () { 216 | function Router() { 217 | _classCallCheck(this, Router); 218 | 219 | riot.observable(this); 220 | this.interceptors = [this.processRoute.bind(this)]; 221 | this.handler = new InitialRoute(); 222 | this.current = new Context("").response; 223 | this.process = this.process.bind(this); 224 | } 225 | 226 | _createClass(Router, [{ 227 | key: 'route', 228 | value: function route(handler) { 229 | this.handler = handler; 230 | } 231 | }, { 232 | key: 'routes', 233 | value: function routes(_routes) { 234 | this.route(new InitialRoute().routes(_routes)); 235 | } 236 | }, { 237 | key: 'use', 238 | value: function use(interceptor) { 239 | this.interceptors.push(interceptor); 240 | } 241 | }, { 242 | key: 'process', 243 | value: function process() { 244 | var params = Array.prototype.slice.call(arguments); 245 | var query = {}; 246 | var uri = params.filter(function (p) { 247 | if (typeof p !== 'string') { 248 | query = p; 249 | return false; 250 | } 251 | return true; 252 | }).join("/"); 253 | if (uri[0] !== '/') uri = "/" + uri; // handle '#any' as '#/any' 254 | var context = new Context(new Request(uri, query)); 255 | if (!this.rootContext) this.rootContext = context; 256 | this.processRequest(context); 257 | return context; 258 | } 259 | }, { 260 | key: 'processRequest', 261 | value: function processRequest(context) { 262 | this.processInterceptors(context); 263 | return this.processResponse(context); 264 | } 265 | }, { 266 | key: 'processResponse', 267 | value: function processResponse(context) { 268 | if (this.isRedirect(context)) { 269 | return this.processRedirect(context); 270 | } 271 | var request = context.request, 272 | response = context.response; 273 | 274 | if (!response.redirectTo) { 275 | this.current = response; 276 | this.rootContext = null; 277 | this.trigger('route:updated', response); 278 | return context; 279 | } 280 | } 281 | }, { 282 | key: 'isRedirect', 283 | value: function isRedirect(context) { 284 | return !!context.response.redirectTo; 285 | } 286 | }, { 287 | key: 'processRedirect', 288 | value: function processRedirect(context) { 289 | var uri = context.response.redirectTo; 290 | this.rootContext.addRedirect(uri); 291 | this.navigateTo(uri); 292 | } 293 | }, { 294 | key: 'navigateTo', 295 | value: function navigateTo() { 296 | var args = Array.prototype.slice.call(arguments); 297 | if (typeof args[1] === 'boolean') { 298 | args.splice(1, 0, ''); 299 | } 300 | this.config.route.apply(null, args); 301 | } 302 | }, { 303 | key: 'processInterceptors', 304 | value: function processInterceptors(context, preInterceptors, postInterceptors) { 305 | var interceptors = (preInterceptors || []).concat(this.interceptors).concat(postInterceptors || []); 306 | var next = function next() { 307 | if (!context.stop) { 308 | var processor = interceptors.shift(); 309 | var request = context.request, 310 | response = context.response; 311 | 312 | if (processor) return processor(request, response, next, context); 313 | } 314 | return context; 315 | }; 316 | return next(); 317 | } 318 | }, { 319 | key: 'processRoute', 320 | value: function processRoute(request, response, next, context) { 321 | this.handler.process(request, response, context); 322 | return next(); 323 | } 324 | }, { 325 | key: 'start', 326 | value: function start() { 327 | this.config.route.start(); 328 | this.exec(); 329 | } 330 | }, { 331 | key: 'exec', 332 | value: function exec() { 333 | this.config.route.exec(this.process); 334 | } 335 | }, { 336 | key: 'configure', 337 | value: function configure(options) { 338 | this.config = extend(true, {}, this.config, options); 339 | if (this.config.route.parser && this.config.parser) this.config.route.parser(this.config.parser); 340 | if (this.config.route.base && this.config.base) this.config.route.base(this.config.base); 341 | this.config.route(this.process); 342 | } 343 | }]); 344 | 345 | return Router; 346 | }(); 347 | 348 | var Context = function () { 349 | function Context(request) { 350 | _classCallCheck(this, Context); 351 | 352 | this.request = typeof request === 'string' ? new Request(request) : request; 353 | this.response = new Response(this.request); 354 | this.redirectStack = []; 355 | } 356 | 357 | _createClass(Context, [{ 358 | key: 'addRedirect', 359 | value: function addRedirect(uri) { 360 | if (this.redirectStack.indexOf(uri) > -1) throw new Error("Cyclic redirection to " + uri + ". Stack = " + this.redirectStack); 361 | this.redirectStack.push(uri); 362 | } 363 | }]); 364 | 365 | return Context; 366 | }(); 367 | 368 | var Handler = function () { 369 | function Handler() { 370 | _classCallCheck(this, Handler); 371 | } 372 | 373 | _createClass(Handler, [{ 374 | key: 'matches', 375 | value: function matches(request) { 376 | return false; 377 | } 378 | }, { 379 | key: 'process', 380 | value: function process(request, response) { 381 | var matcher = this.matches(request); 382 | if (!matcher) return this.routeMiss(request, response); 383 | return this.routeMatch(request, response, matcher); 384 | } 385 | }, { 386 | key: 'routeMatch', 387 | value: function routeMatch(request, response, matcher) { 388 | response.add(matcher); 389 | return true; 390 | } 391 | }, { 392 | key: 'routeMiss', 393 | value: function routeMiss(request, response) { 394 | return false; 395 | } 396 | }, { 397 | key: 'processRoutes', 398 | value: function processRoutes(request, response, routes) { 399 | if (routes && routes.length) { 400 | var t = routes.length; 401 | for (var i = 0; i < t; i++) { 402 | var route = routes[i]; 403 | if (route.process(request, response)) return true; 404 | } 405 | return false; 406 | } 407 | } 408 | }, { 409 | key: 'createRequest', 410 | value: function createRequest(request, matcher) { 411 | return new ChildRequest(request, matcher); 412 | } 413 | }]); 414 | 415 | return Handler; 416 | }(); 417 | 418 | var Route = function (_Handler) { 419 | _inherits(Route, _Handler); 420 | 421 | function Route(options) { 422 | _classCallCheck(this, Route); 423 | 424 | var _this = _possibleConstructorReturn(this, (Route.__proto__ || Object.getPrototypeOf(Route)).call(this, options)); 425 | 426 | options = options || {}; 427 | _this.tag = options.tag; 428 | _this.api = options.api; 429 | _this.path = options.path; 430 | _this.name = options.name; 431 | _this.updatable = options.updatable; 432 | _this.pathParameterNames = []; 433 | var path = _this.getPath().replace(/^\//, ""); 434 | _this.pattern = "^/?" + path.replace(/:([^/]+)/g, function (ignored, group) { 435 | this.pathParameterNames.push(group); 436 | return "([^/]+)"; 437 | }.bind(_this)) + "(:?/|$)"; 438 | _this.regex = new RegExp(_this.pattern); 439 | return _this; 440 | } 441 | 442 | _createClass(Route, [{ 443 | key: 'routes', 444 | value: function routes(_routes2) { 445 | var redirectRoutes = _routes2.filter(function (r) { 446 | return r instanceof RedirectRoute; 447 | }); 448 | var defaultRoutes = _routes2.filter(function (r) { 449 | return r instanceof DefaultRoute; 450 | }); 451 | var notFoundRoutes = _routes2.filter(function (r) { 452 | return r instanceof NotFoundRoute; 453 | }); 454 | var otherRoutes = _routes2.filter(function (r) { 455 | return redirectRoutes.indexOf(r) === -1 && defaultRoutes.indexOf(r) === -1 && notFoundRoutes.indexOf(r) === -1; 456 | }); 457 | if (notFoundRoutes.length > 1) error("Can't use more than one NotFoundRoute per route. --> " + this.getPath()); 458 | if (defaultRoutes.length > 1) error("Can't use more than one DefaultRoute per route. --> " + this.getPath()); 459 | this._routes = [].concat(redirectRoutes).concat(otherRoutes).concat(defaultRoutes).concat(notFoundRoutes); 460 | return this; 461 | } 462 | }, { 463 | key: 'matches', 464 | value: function matches(request) { 465 | var matcher = this.regex.exec(request.uri); 466 | if (matcher) { 467 | var params = {}; 468 | for (var i in this.pathParameterNames) { 469 | if (this.pathParameterNames.hasOwnProperty(i)) { 470 | var name = this.pathParameterNames[i]; 471 | params[name] = decodeURIComponent(matcher[parseInt(i, 10) + 1]); 472 | } 473 | } 474 | return { 475 | route: this, 476 | tag: this.tag, 477 | api: this.api, 478 | found: matcher[0], 479 | params: params 480 | }; 481 | } 482 | return false; 483 | } 484 | }, { 485 | key: 'routeMatch', 486 | value: function routeMatch(request, response, matcher) { 487 | var matches = _get(Route.prototype.__proto__ || Object.getPrototypeOf(Route.prototype), 'routeMatch', this).call(this, request, response, matcher); 488 | this.processRoutes(request, response, matcher); 489 | return matches; 490 | } 491 | }, { 492 | key: 'processRoutes', 493 | value: function processRoutes(request, response, matcher) { 494 | return _get(Route.prototype.__proto__ || Object.getPrototypeOf(Route.prototype), 'processRoutes', this).call(this, this.createRequest(request, matcher), response, this._routes); 495 | } 496 | }, { 497 | key: 'getPath', 498 | value: function getPath() { 499 | return this.name || this.path || (typeof this.tag === 'string' ? this.tag : ''); 500 | } 501 | }]); 502 | 503 | return Route; 504 | }(Handler); 505 | 506 | var InitialRoute = function (_Route) { 507 | _inherits(InitialRoute, _Route); 508 | 509 | function InitialRoute() { 510 | _classCallCheck(this, InitialRoute); 511 | 512 | return _possibleConstructorReturn(this, (InitialRoute.__proto__ || Object.getPrototypeOf(InitialRoute)).apply(this, arguments)); 513 | } 514 | 515 | return InitialRoute; 516 | }(Route); 517 | 518 | var ChildRequest = function ChildRequest(request, matcher) { 519 | _classCallCheck(this, ChildRequest); 520 | 521 | this.request = request; 522 | this.matcher = matcher; 523 | this.uri = this.request.uri.substring(matcher.found.length); 524 | this.parentUri = this.request.uri.substring(0, matcher.found.length); 525 | this.query = this.request.query; 526 | }; 527 | 528 | var NotFoundRoute = function (_Handler2) { 529 | _inherits(NotFoundRoute, _Handler2); 530 | 531 | function NotFoundRoute(options) { 532 | _classCallCheck(this, NotFoundRoute); 533 | 534 | var _this3 = _possibleConstructorReturn(this, (NotFoundRoute.__proto__ || Object.getPrototypeOf(NotFoundRoute)).call(this, options)); 535 | 536 | options = options || {}; 537 | _this3.tag = options.tag; 538 | _this3.api = options.api; 539 | return _this3; 540 | } 541 | 542 | _createClass(NotFoundRoute, [{ 543 | key: 'matches', 544 | value: function matches(request) { 545 | return { 546 | route: this, 547 | tag: this.tag, 548 | api: this.api, 549 | found: request.uri 550 | }; 551 | } 552 | }]); 553 | 554 | return NotFoundRoute; 555 | }(Handler); 556 | 557 | var RedirectRoute = function (_Handler3) { 558 | _inherits(RedirectRoute, _Handler3); 559 | 560 | function RedirectRoute(options) { 561 | _classCallCheck(this, RedirectRoute); 562 | 563 | var _this4 = _possibleConstructorReturn(this, (RedirectRoute.__proto__ || Object.getPrototypeOf(RedirectRoute)).call(this, options)); 564 | 565 | options = options || {}; 566 | _this4.from = options.from; 567 | _this4.to = options.to; 568 | _this4.pattern = "(^/?)" + _this4.from + "(/|$)"; 569 | _this4.regex = new RegExp(_this4.pattern); 570 | return _this4; 571 | } 572 | 573 | _createClass(RedirectRoute, [{ 574 | key: 'process', 575 | value: function process(request, response) { 576 | var uri = request.uri.replace(this.regex, "$1" + this.to + "$2"); 577 | if (uri !== request.uri) { 578 | var parent = request.parentUri || ""; 579 | response.redirectTo = parent + uri; 580 | return true; 581 | } 582 | } 583 | }]); 584 | 585 | return RedirectRoute; 586 | }(Handler); 587 | 588 | var DefaultRoute = function (_Handler4) { 589 | _inherits(DefaultRoute, _Handler4); 590 | 591 | function DefaultRoute(options) { 592 | _classCallCheck(this, DefaultRoute); 593 | 594 | var _this5 = _possibleConstructorReturn(this, (DefaultRoute.__proto__ || Object.getPrototypeOf(DefaultRoute)).call(this, options)); 595 | 596 | options = options || {}; 597 | _this5.tag = options.tag; 598 | _this5.api = options.api; 599 | return _this5; 600 | } 601 | 602 | _createClass(DefaultRoute, [{ 603 | key: 'matches', 604 | value: function matches(request) { 605 | var uri = request.uri.trim(); 606 | if (uri === "/" || uri === "") return { 607 | route: this, 608 | tag: this.tag, 609 | api: this.api, 610 | found: uri 611 | }; 612 | } 613 | }]); 614 | 615 | return DefaultRoute; 616 | }(Handler); 617 | 618 | var Request = function Request(uri, query) { 619 | _classCallCheck(this, Request); 620 | 621 | this.uri = uri; 622 | this.query = query; 623 | }; 624 | 625 | var Response = function () { 626 | function Response(request) { 627 | _classCallCheck(this, Response); 628 | 629 | this.uri = request.uri; 630 | this.matches = []; 631 | this.params = {}; 632 | this.query = request.query; 633 | } 634 | 635 | _createClass(Response, [{ 636 | key: 'add', 637 | value: function add(matcher) { 638 | this.matches.push(matcher); 639 | var params = matcher.params; 640 | if (params) { 641 | for (var key in params) { 642 | if (params.hasOwnProperty(key)) { 643 | this.params[key] = params[key]; 644 | } 645 | } 646 | } 647 | } 648 | }, { 649 | key: 'get', 650 | value: function get(index) { 651 | return this.matches[index]; 652 | } 653 | }, { 654 | key: 'size', 655 | value: function size() { 656 | return this.matches.length; 657 | } 658 | }, { 659 | key: 'isEmpty', 660 | value: function isEmpty() { 661 | return this.matches.length; 662 | } 663 | }]); 664 | 665 | return Response; 666 | }(); 667 | 668 | function registerTag(router) { 669 | riot.tag('route', '', '', '', function (opts) { 670 | this.calculateLevel = function (target) { 671 | var level = 0; 672 | if (target.parent) level += this.calculateLevel(target.parent); 673 | if (target.opts.__router_level) level += target.opts.__router_level; 674 | if (target.__router_tag) level += 1; 675 | return level; 676 | }.bind(this); 677 | 678 | this.normalizeTag = function (tag, api, options) { 679 | var result = tag(api, options); 680 | if (typeof result === 'string') { 681 | tag = result; 682 | } else { 683 | tag = result.tag || tag; 684 | api = result.api || api; 685 | } 686 | return [tag, api, options]; 687 | }; 688 | 689 | this.unmountTag = function () { 690 | if (this.instance) this.instance.unmount(true); 691 | }; 692 | 693 | this.mountTag = function (tag, api, options) { 694 | if (typeof tag === 'function') { 695 | var _normalizeTag = this.normalizeTag(tag, api, options); 696 | 697 | var _normalizeTag2 = _slicedToArray(_normalizeTag, 3); 698 | 699 | tag = _normalizeTag2[0]; 700 | api = _normalizeTag2[1]; 701 | options = _normalizeTag2[2]; 702 | } 703 | if (this.canUpdate(tag, api, options)) { 704 | this.instance.update(api); 705 | } else { 706 | this.unmountTag(); 707 | if (tag) { 708 | this.root.replaceChild(document.createElement(tag), this.root.children[0]); 709 | try { 710 | this.instance = riot.mount(this.root.children[0], tag, api)[0]; 711 | } catch (e) { 712 | error("Error when mounting tag '" + tag + "'.", e); 713 | return; 714 | } 715 | this.instanceTag = tag; 716 | this.instanceApi = api; 717 | } 718 | } 719 | }; 720 | 721 | this.canUpdate = function (tag, api, options) { 722 | if (!router.config.updatable && !opts.updatable && !options.updatable || !this.instance || !this.instance.isMounted || this.instanceTag !== tag) return false; 723 | return true; 724 | }; 725 | 726 | this.updateRoute = function () { 727 | var mount = { 728 | tag: null 729 | }; 730 | if (router && router.current) { 731 | var response = router.current; 732 | if (this.level <= response.size()) { 733 | var matcher = response.get(this.level); 734 | if (matcher) { 735 | var params = matcher.params || {}; 736 | var query = response.query || {}; 737 | var api = extend(true, {}, opts, query, matcher.api, params, { 738 | __router_level: this.level, 739 | query: query 740 | }); 741 | mount = { 742 | tag: matcher.tag, 743 | api: api, 744 | updatable: matcher.route.updatable 745 | }; 746 | } 747 | } 748 | } 749 | if (mount.tag) this.mountTag(mount.tag, mount.api, mount);else this.unmountTag(); 750 | }.bind(this); 751 | 752 | this.__router_tag = 'route'; 753 | this.level = this.calculateLevel(this); 754 | router.on('route:updated', this.updateRoute); 755 | this.on('unmount', function () { 756 | router.off('route:updated', this.updateRoute); 757 | this.unmountTag(); 758 | }.bind(this)); 759 | this.on('mount', this.updateRoute); 760 | }); 761 | } 762 | 763 | function detectRoute() { 764 | var route = riot.route || window && window.route || global && global.route; 765 | return route; 766 | } 767 | 768 | function create(config) { 769 | var router = new Router(); 770 | router.configure(extend(true, { 771 | updatable: true, 772 | route: detectRoute(), 773 | base: '#', 774 | parser: function customRiotParser(path) { 775 | var raw = path.split('?'), 776 | uri = raw[0].split('/'), 777 | query = raw[1], 778 | params = {}; 779 | if (query) { 780 | query.split('&').forEach(function (v) { 781 | var c = v.split('='); 782 | params[c[0]] = c[1]; 783 | }); 784 | } 785 | uri.push(params); 786 | return uri; 787 | } 788 | }, config)); 789 | registerTag(router); 790 | if (!Router.instance) Router.instance = router; 791 | return router; 792 | } 793 | Router.create = create; 794 | Router.Route = Route; 795 | Router.DefaultRoute = DefaultRoute; 796 | Router.RedirectRoute = RedirectRoute; 797 | Router.NotFoundRoute = NotFoundRoute; 798 | Router._ = { 799 | Response: Response, 800 | Request: Request 801 | }; 802 | module.exports = Router; 803 | }); 804 | /* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }()))) 805 | 806 | /***/ }, 807 | /* 5 */ 808 | /***/ function(module, exports) { 809 | 810 | 'use strict'; 811 | 812 | var hasOwn = Object.prototype.hasOwnProperty; 813 | var toStr = Object.prototype.toString; 814 | 815 | var isArray = function isArray(arr) { 816 | if (typeof Array.isArray === 'function') { 817 | return Array.isArray(arr); 818 | } 819 | 820 | return toStr.call(arr) === '[object Array]'; 821 | }; 822 | 823 | var isPlainObject = function isPlainObject(obj) { 824 | if (!obj || toStr.call(obj) !== '[object Object]') { 825 | return false; 826 | } 827 | 828 | var hasOwnConstructor = hasOwn.call(obj, 'constructor'); 829 | var hasIsPrototypeOf = obj.constructor && obj.constructor.prototype && hasOwn.call(obj.constructor.prototype, 'isPrototypeOf'); 830 | // Not own constructor property must be Object 831 | if (obj.constructor && !hasOwnConstructor && !hasIsPrototypeOf) { 832 | return false; 833 | } 834 | 835 | // Own properties are enumerated firstly, so to speed up, 836 | // if last one is own, then all properties are own. 837 | var key; 838 | for (key in obj) {/**/} 839 | 840 | return typeof key === 'undefined' || hasOwn.call(obj, key); 841 | }; 842 | 843 | module.exports = function extend() { 844 | var options, name, src, copy, copyIsArray, clone, 845 | target = arguments[0], 846 | i = 1, 847 | length = arguments.length, 848 | deep = false; 849 | 850 | // Handle a deep copy situation 851 | if (typeof target === 'boolean') { 852 | deep = target; 853 | target = arguments[1] || {}; 854 | // skip the boolean and the target 855 | i = 2; 856 | } else if ((typeof target !== 'object' && typeof target !== 'function') || target == null) { 857 | target = {}; 858 | } 859 | 860 | for (; i < length; ++i) { 861 | options = arguments[i]; 862 | // Only deal with non-null/undefined values 863 | if (options != null) { 864 | // Extend the base object 865 | for (name in options) { 866 | src = target[name]; 867 | copy = options[name]; 868 | 869 | // Prevent never-ending loop 870 | if (target !== copy) { 871 | // Recurse if we're merging plain objects or arrays 872 | if (deep && copy && (isPlainObject(copy) || (copyIsArray = isArray(copy)))) { 873 | if (copyIsArray) { 874 | copyIsArray = false; 875 | clone = src && isArray(src) ? src : []; 876 | } else { 877 | clone = src && isPlainObject(src) ? src : {}; 878 | } 879 | 880 | // Never move original objects, clone them 881 | target[name] = extend(deep, clone, copy); 882 | 883 | // Don't bring in undefined values 884 | } else if (typeof copy !== 'undefined') { 885 | target[name] = copy; 886 | } 887 | } 888 | } 889 | } 890 | } 891 | 892 | // Return the modified object 893 | return target; 894 | }; 895 | 896 | 897 | 898 | /***/ } 899 | /******/ ]) 900 | }); 901 | ; 902 | //# sourceMappingURL=router.core.js.map -------------------------------------------------------------------------------- /dist/router.core.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["webpack:///webpack/universalModuleDefinition?5ca6","webpack:///webpack/bootstrap 56bfc5db8623b637755d?e9a3","webpack:///./router.core.js","webpack:///external \"riot\"?b5ff","webpack:///./src/router.js?707b","webpack:///./~/extend/index.js?36c8"],"names":["Router","module","exports","riot","extend","error","console","observable","interceptors","processRoute","bind","handler","InitialRoute","current","Context","response","process","routes","route","interceptor","push","params","Array","prototype","slice","call","arguments","query","uri","filter","p","join","context","Request","rootContext","processRequest","processInterceptors","processResponse","isRedirect","processRedirect","request","redirectTo","trigger","addRedirect","navigateTo","args","splice","config","apply","preInterceptors","postInterceptors","concat","next","stop","processor","shift","start","exec","options","parser","base","Response","redirectStack","indexOf","Error","Handler","matcher","matches","routeMiss","routeMatch","add","length","t","i","ChildRequest","Route","tag","api","path","name","updatable","pathParameterNames","getPath","replace","pattern","ignored","group","regex","RegExp","redirectRoutes","r","RedirectRoute","defaultRoutes","DefaultRoute","notFoundRoutes","NotFoundRoute","otherRoutes","_routes","hasOwnProperty","decodeURIComponent","parseInt","found","processRoutes","createRequest","substring","parentUri","from","to","parent","trim","key","index","registerTag","router","opts","calculateLevel","target","level","__router_level","__router_tag","normalizeTag","result","unmountTag","instance","unmount","mountTag","canUpdate","update","root","replaceChild","document","createElement","children","mount","e","instanceTag","instanceApi","isMounted","updateRoute","size","get","on","off","detectRoute","window","global","create","configure","customRiotParser","raw","split","forEach","v","c","_"],"mappings":"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","file":"router.core.js","sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory(require(\"riot\"));\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([\"riot\"], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"Router\"] = factory(require(\"riot\"));\n\telse\n\t\troot[\"Router\"] = factory(root[\"riot\"]);\n})(this, function(__WEBPACK_EXTERNAL_MODULE_1__) {\nreturn \n\n\n// WEBPACK FOOTER //\n// webpack/universalModuleDefinition"," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\texports: {},\n \t\t\tid: moduleId,\n \t\t\tloaded: false\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.loaded = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"/dist/\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(0);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap 56bfc5db8623b637755d","var Router = require('./src/router.js');\nmodule.exports = Router;\n\n\n// WEBPACK FOOTER //\n// ./router.core.js","module.exports = __WEBPACK_EXTERNAL_MODULE_1__;\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"riot\"\n// module id = 1\n// module chunks = 0 1","var riot = require('riot');\nvar extend = require('extend');\nvar error = console && console.error || function () {};\n\nclass Router {\n constructor() {\n riot.observable(this);\n this.interceptors = [this.processRoute.bind(this)];\n this.handler = new InitialRoute();\n this.current = new Context(\"\").response;\n this.process = this.process.bind(this);\n }\n\n route(handler) {\n this.handler = handler;\n }\n\n routes(routes) {\n this.route(new InitialRoute().routes(routes));\n }\n\n use(interceptor) {\n this.interceptors.push(interceptor);\n }\n\n process() {\n var params = Array.prototype.slice.call(arguments);\n var query = {};\n var uri = params.filter(function (p) {\n if (typeof (p) !== 'string') {\n query = p;\n return false;\n }\n return true;\n }).join(\"/\");\n if (uri[0] !== '/') uri = \"/\" + uri; // handle '#any' as '#/any'\n var context = new Context(new Request(uri, query));\n if (!this.rootContext) this.rootContext = context;\n this.processRequest(context);\n return context;\n }\n\n processRequest(context) {\n this.processInterceptors(context);\n return this.processResponse(context);\n }\n\n processResponse(context) {\n if (this.isRedirect(context)) {\n return this.processRedirect(context);\n }\n var {\n request,\n response\n } = context;\n if (!response.redirectTo) {\n this.current = response;\n this.rootContext = null;\n this.trigger('route:updated', response);\n return context;\n }\n }\n\n isRedirect(context) {\n return !!context.response.redirectTo;\n }\n\n processRedirect(context) {\n var uri = context.response.redirectTo;\n this.rootContext.addRedirect(uri);\n this.navigateTo(uri);\n }\n\n navigateTo() {\n var args = Array.prototype.slice.call(arguments);\n if (typeof(args[1]) === 'boolean') {\n args.splice(1, 0, '');\n }\n this.config.route.apply(null, args);\n }\n\n processInterceptors(context, preInterceptors, postInterceptors) {\n var interceptors = (preInterceptors || []).concat(this.interceptors).concat(postInterceptors || []);\n var next = function next() {\n if (!context.stop) {\n var processor = interceptors.shift();\n var {\n request,\n response\n } = context;\n if (processor)\n return processor(request, response, next, context);\n }\n return context;\n };\n return next();\n }\n\n processRoute(request, response, next, context) {\n this.handler.process(request, response, context);\n return next();\n }\n\n start() {\n this.config.route.start();\n this.exec();\n }\n\n exec() {\n this.config.route.exec(this.process);\n }\n\n configure(options) {\n this.config = extend(true, {}, this.config, options);\n if (this.config.route.parser && this.config.parser)\n this.config.route.parser(this.config.parser);\n if (this.config.route.base && this.config.base)\n this.config.route.base(this.config.base);\n this.config.route(this.process);\n }\n\n}\n\nclass Context {\n constructor(request) {\n this.request = typeof (request) === 'string' ? new Request(request) : request;\n this.response = new Response(this.request);\n this.redirectStack = [];\n }\n\n addRedirect(uri) {\n if (this.redirectStack.indexOf(uri) > -1)\n throw new Error(\"Cyclic redirection to \" + uri + \". Stack = \" + this.redirectStack);\n this.redirectStack.push(uri);\n }\n\n}\n\nclass Handler {\n constructor() {}\n\n matches(request) {\n return false;\n }\n\n process(request, response) {\n var matcher = this.matches(request);\n if (!matcher) return this.routeMiss(request, response);\n return this.routeMatch(request, response, matcher);\n }\n\n routeMatch(request, response, matcher) {\n response.add(matcher);\n return true;\n }\n\n routeMiss(request, response) {\n return false;\n }\n\n processRoutes(request, response, routes) {\n if (routes && routes.length) {\n var t = routes.length;\n for (var i = 0; i < t; i++) {\n var route = routes[i];\n if (route.process(request, response))\n return true;\n }\n return false;\n }\n }\n\n createRequest(request, matcher) {\n return new ChildRequest(request, matcher);\n }\n}\n\nclass Route extends Handler {\n constructor(options) {\n super(options);\n options = options || {};\n this.tag = options.tag;\n this.api = options.api;\n this.path = options.path;\n this.name = options.name;\n this.updatable = options.updatable;\n this.pathParameterNames = [];\n var path = this.getPath().replace(/^\\//, \"\");\n this.pattern = \"^/?\" + path.replace(/:([^/]+)/g, function (ignored, group) {\n this.pathParameterNames.push(group);\n return \"([^/]+)\";\n }.bind(this)) + \"(:?/|$)\";\n this.regex = new RegExp(this.pattern);\n }\n\n routes(routes) {\n var redirectRoutes = routes.filter(function (r) {\n return r instanceof RedirectRoute;\n });\n var defaultRoutes = routes.filter(function (r) {\n return r instanceof DefaultRoute;\n });\n var notFoundRoutes = routes.filter(function (r) {\n return r instanceof NotFoundRoute;\n });\n var otherRoutes = routes.filter(function (r) {\n return redirectRoutes.indexOf(r) === -1 &&\n defaultRoutes.indexOf(r) === -1 &&\n notFoundRoutes.indexOf(r) === -1;\n });\n if (notFoundRoutes.length > 1) error(\"Can't use more than one NotFoundRoute per route. --> \" + this.getPath());\n if (defaultRoutes.length > 1) error(\"Can't use more than one DefaultRoute per route. --> \" + this.getPath());\n this._routes = [].concat(redirectRoutes).concat(otherRoutes).concat(defaultRoutes).concat(notFoundRoutes);\n return this;\n }\n\n matches(request) {\n var matcher = this.regex.exec(request.uri);\n if (matcher) {\n var params = {};\n for (var i in this.pathParameterNames) {\n if (this.pathParameterNames.hasOwnProperty(i)) {\n var name = this.pathParameterNames[i];\n params[name] = decodeURIComponent(matcher[parseInt(i, 10) + 1]);\n }\n }\n return {\n route: this,\n tag: this.tag,\n api: this.api,\n found: matcher[0],\n params: params\n };\n }\n return false;\n }\n\n routeMatch(request, response, matcher) {\n var matches = super.routeMatch(request, response, matcher);\n this.processRoutes(request, response, matcher);\n return matches;\n }\n\n processRoutes(request, response, matcher) {\n return super.processRoutes(this.createRequest(request, matcher), response, this._routes);\n }\n\n getPath() {\n return this.name || this.path || (typeof this.tag === 'string' ? this.tag : '');\n }\n}\n\nclass InitialRoute extends Route {\n\n}\n\nclass ChildRequest {\n constructor(request, matcher) {\n this.request = request;\n this.matcher = matcher;\n this.uri = this.request.uri.substring(matcher.found.length);\n this.parentUri = this.request.uri.substring(0, matcher.found.length);\n this.query = this.request.query;\n }\n}\n\nclass NotFoundRoute extends Handler {\n constructor(options) {\n super(options);\n options = options || {};\n this.tag = options.tag;\n this.api = options.api;\n }\n matches(request) {\n return {\n route: this,\n tag: this.tag,\n api: this.api,\n found: request.uri\n };\n }\n}\n\nclass RedirectRoute extends Handler {\n constructor(options) {\n super(options);\n options = options || {};\n this.from = options.from;\n this.to = options.to;\n this.pattern = \"(^/?)\" + this.from + \"(/|$)\";\n this.regex = new RegExp(this.pattern);\n }\n\n process(request, response) {\n var uri = request.uri.replace(this.regex, \"$1\" + this.to + \"$2\");\n if (uri !== request.uri) {\n var parent = request.parentUri || \"\";\n response.redirectTo = parent + uri;\n return true;\n }\n }\n\n}\n\nclass DefaultRoute extends Handler {\n constructor(options) {\n super(options);\n options = options || {};\n this.tag = options.tag;\n this.api = options.api;\n }\n matches(request) {\n var uri = request.uri.trim();\n if (uri === \"/\" || uri === \"\")\n return {\n route: this,\n tag: this.tag,\n api: this.api,\n found: uri\n };\n }\n}\n\nclass Request {\n constructor(uri, query) {\n this.uri = uri;\n this.query = query;\n }\n}\n\nclass Response {\n constructor(request) {\n this.uri = request.uri;\n this.matches = [];\n this.params = {};\n this.query = request.query;\n }\n add(matcher) {\n this.matches.push(matcher);\n var params = matcher.params;\n if (params) {\n for (var key in params) {\n if (params.hasOwnProperty(key)) {\n this.params[key] = params[key];\n }\n }\n }\n }\n\n get(index) {\n return this.matches[index];\n }\n\n size() {\n return this.matches.length;\n }\n\n isEmpty() {\n return this.matches.length;\n }\n\n}\n\nfunction registerTag(router) {\n riot.tag('route', '', '', '', function (opts) {\n this.calculateLevel = function (target) {\n var level = 0;\n if (target.parent) level += this.calculateLevel(target.parent);\n if (target.opts.__router_level) level += target.opts.__router_level;\n if (target.__router_tag) level += 1;\n return level;\n }.bind(this);\n\n this.normalizeTag = function (tag, api, options) {\n var result = tag(api, options);\n if (typeof result === 'string') {\n tag = result;\n } else {\n tag = result.tag || tag;\n api = result.api || api;\n }\n return [tag, api, options];\n }\n\n this.unmountTag = function () {\n if (this.instance)\n this.instance.unmount(true);\n }\n\n this.mountTag = function (tag, api, options) {\n if (typeof tag === 'function') {\n [tag, api, options] = this.normalizeTag(tag, api, options);\n }\n if (this.canUpdate(tag, api, options)) {\n this.instance.update(api);\n } else {\n this.unmountTag();\n if (tag) {\n this.root.replaceChild(document.createElement(tag), this.root.children[0]);\n try {\n this.instance = riot.mount(this.root.children[0], tag, api)[0];\n } catch (e) {\n error(\"Error when mounting tag '\" + tag + \"'.\", e);\n return;\n }\n this.instanceTag = tag;\n this.instanceApi = api;\n }\n }\n }\n\n this.canUpdate = function (tag, api, options) {\n if ((!router.config.updatable && !opts.updatable && !options.updatable) ||\n !this.instance ||\n !this.instance.isMounted ||\n this.instanceTag !== tag)\n return false;\n return true;\n }\n\n this.updateRoute = function () {\n var mount = {\n tag: null\n };\n if (router && router.current) {\n var response = router.current;\n if (this.level <= response.size()) {\n var matcher = response.get(this.level);\n if (matcher) {\n var params = matcher.params || {};\n var query = response.query || {};\n var api = extend(true, {}, opts, query, matcher.api, params, {\n __router_level: this.level,\n query: query\n });\n mount = {\n tag: matcher.tag,\n api: api,\n updatable: matcher.route.updatable\n };\n }\n }\n }\n if (mount.tag)\n this.mountTag(mount.tag, mount.api, mount);\n else\n this.unmountTag();\n }.bind(this);\n\n this.__router_tag = 'route';\n this.level = this.calculateLevel(this);\n router.on('route:updated', this.updateRoute);\n this.on('unmount', function () {\n router.off('route:updated', this.updateRoute);\n this.unmountTag();\n }.bind(this));\n this.on('mount', this.updateRoute);\n });\n}\n\nfunction detectRoute() {\n var route = riot.route ||\n (window && window.route) ||\n (global && global.route);\n return route;\n}\n\nfunction create(config) {\n var router = new Router();\n router.configure(extend(true, {\n updatable: true,\n route: detectRoute(),\n base: '#',\n parser: function customRiotParser(path) {\n var raw = path.split('?'),\n uri = raw[0].split('/'),\n query = raw[1],\n params = {}\n if (query) {\n query.split('&').forEach(function (v) {\n var c = v.split('=')\n params[c[0]] = c[1]\n })\n }\n uri.push(params)\n return uri\n }\n }, config));\n registerTag(router);\n if (!Router.instance) Router.instance = router;\n return router;\n}\nRouter.create = create;\nRouter.Route = Route;\nRouter.DefaultRoute = DefaultRoute;\nRouter.RedirectRoute = RedirectRoute;\nRouter.NotFoundRoute = NotFoundRoute;\nRouter._ = {\n Response: Response,\n Request: Request\n};\nmodule.exports = Router;\n\n\n\n// WEBPACK FOOTER //\n// ./src/router.js","'use strict';\n\nvar hasOwn = Object.prototype.hasOwnProperty;\nvar toStr = Object.prototype.toString;\n\nvar isArray = function isArray(arr) {\n\tif (typeof Array.isArray === 'function') {\n\t\treturn Array.isArray(arr);\n\t}\n\n\treturn toStr.call(arr) === '[object Array]';\n};\n\nvar isPlainObject = function isPlainObject(obj) {\n\tif (!obj || toStr.call(obj) !== '[object Object]') {\n\t\treturn false;\n\t}\n\n\tvar hasOwnConstructor = hasOwn.call(obj, 'constructor');\n\tvar hasIsPrototypeOf = obj.constructor && obj.constructor.prototype && hasOwn.call(obj.constructor.prototype, 'isPrototypeOf');\n\t// Not own constructor property must be Object\n\tif (obj.constructor && !hasOwnConstructor && !hasIsPrototypeOf) {\n\t\treturn false;\n\t}\n\n\t// Own properties are enumerated firstly, so to speed up,\n\t// if last one is own, then all properties are own.\n\tvar key;\n\tfor (key in obj) {/**/}\n\n\treturn typeof key === 'undefined' || hasOwn.call(obj, key);\n};\n\nmodule.exports = function extend() {\n\tvar options, name, src, copy, copyIsArray, clone,\n\t\ttarget = arguments[0],\n\t\ti = 1,\n\t\tlength = arguments.length,\n\t\tdeep = false;\n\n\t// Handle a deep copy situation\n\tif (typeof target === 'boolean') {\n\t\tdeep = target;\n\t\ttarget = arguments[1] || {};\n\t\t// skip the boolean and the target\n\t\ti = 2;\n\t} else if ((typeof target !== 'object' && typeof target !== 'function') || target == null) {\n\t\ttarget = {};\n\t}\n\n\tfor (; i < length; ++i) {\n\t\toptions = arguments[i];\n\t\t// Only deal with non-null/undefined values\n\t\tif (options != null) {\n\t\t\t// Extend the base object\n\t\t\tfor (name in options) {\n\t\t\t\tsrc = target[name];\n\t\t\t\tcopy = options[name];\n\n\t\t\t\t// Prevent never-ending loop\n\t\t\t\tif (target !== copy) {\n\t\t\t\t\t// Recurse if we're merging plain objects or arrays\n\t\t\t\t\tif (deep && copy && (isPlainObject(copy) || (copyIsArray = isArray(copy)))) {\n\t\t\t\t\t\tif (copyIsArray) {\n\t\t\t\t\t\t\tcopyIsArray = false;\n\t\t\t\t\t\t\tclone = src && isArray(src) ? src : [];\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tclone = src && isPlainObject(src) ? src : {};\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Never move original objects, clone them\n\t\t\t\t\t\ttarget[name] = extend(deep, clone, copy);\n\n\t\t\t\t\t// Don't bring in undefined values\n\t\t\t\t\t} else if (typeof copy !== 'undefined') {\n\t\t\t\t\t\ttarget[name] = copy;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Return the modified object\n\treturn target;\n};\n\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/extend/index.js\n// module id = 5\n// module chunks = 0 1"],"sourceRoot":""} -------------------------------------------------------------------------------- /dist/router.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["webpack:///webpack/universalModuleDefinition","webpack:///webpack/bootstrap 56bfc5db8623b637755d","webpack:///./router.js","webpack:///external \"riot\"","webpack:///./~/riot-route/dist/cjs.route.js","webpack:///./~/riot-observable/dist/observable.js","webpack:///./src/router.js","webpack:///./~/extend/index.js"],"names":["riot","route","Router","router","create","window","module","exports","extend","error","console","observable","interceptors","processRoute","bind","handler","InitialRoute","current","Context","response","process","routes","interceptor","push","params","Array","prototype","slice","call","arguments","query","uri","filter","p","join","context","Request","rootContext","processRequest","processInterceptors","processResponse","isRedirect","processRedirect","request","redirectTo","trigger","addRedirect","navigateTo","args","splice","config","apply","preInterceptors","postInterceptors","concat","next","stop","processor","shift","start","exec","options","parser","base","Response","redirectStack","indexOf","Error","Handler","matcher","matches","routeMiss","routeMatch","add","length","t","i","ChildRequest","Route","tag","api","path","name","updatable","pathParameterNames","getPath","replace","pattern","ignored","group","regex","RegExp","redirectRoutes","r","RedirectRoute","defaultRoutes","DefaultRoute","notFoundRoutes","NotFoundRoute","otherRoutes","_routes","hasOwnProperty","decodeURIComponent","parseInt","found","processRoutes","createRequest","substring","parentUri","from","to","parent","trim","key","index","registerTag","opts","calculateLevel","target","level","__router_level","__router_tag","normalizeTag","result","unmountTag","instance","unmount","mountTag","canUpdate","update","root","replaceChild","document","createElement","children","mount","e","instanceTag","instanceApi","isMounted","updateRoute","size","get","on","off","detectRoute","global","configure","customRiotParser","raw","split","forEach","v","c","_"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;AACD,O;ACVA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,uBAAe;AACf;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;;;;;;;;mDCtCmB,sB,EACC,sB,EACC,sB;;iCAFF,M,WACC,Y,WACC,iB;;;;;;;;4BAFjBA,I,EACAC,K,EACAC,M;;;AACJ,SAAIC,SAASD,OAAOE,MAAP,CAAc,EAACH,OAAOA,KAAR,EAAd,CAAb;AACA,SAAII,MAAJ,EAAY;AACRA,gBAAOF,MAAP,GAAgBA,MAAhB;AACH;AACDG,YAAOC,OAAP,GAAiBL,MAAjB;;;;;;;ACPA,gD;;;;;;ACAA;;AAEA,gCAA+B,iFAAiF;;AAEhH;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,YAAW,OAAO;AAClB,cAAa,MAAM;AACnB;AACA;AACA;AACA;;AAEA;AACA;AACA,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB,cAAa,MAAM;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,cAAa;AACb;;AAEA;AACA;AACA,cAAa,SAAS;AACtB,cAAa,OAAO;AACpB,cAAa,SAAS;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,YAAW,QAAQ;AACnB;AACA;AACA;AACA;AACA;AACA;AACA,kBAAiB,YAAY;AAC7B;;AAEA;AACA;AACA;AACA;AACA;AACA,oBAAmB;AACnB;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,YAAW,OAAO;AAClB,cAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;AACA;AACA,YAAW,OAAO;AAClB,cAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,gDAA+C;;AAE/C;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA,wCAAuC,SAAS,EAAE;AAClD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA,sCAAqC,oBAAoB;;AAEzD;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA,SAAQ;;AAER;AACA;;AAEA;AACA;AACA,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB,YAAW,QAAQ;AACnB,cAAa,QAAQ;AACrB;AACA;AACA;AACA,eAAc;;AAEd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW,kBAAkB;AAC7B,YAAW,yBAAyB;AACpC,YAAW,QAAQ;AACnB;AACA;AACA,0DAAyD,mCAAmC;AAC5F,qBAAoB,uBAAuB;AAC3C,SAAQ,oBAAoB;AAC5B;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,YAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;;AAEA;AACA;AACA,YAAW,OAAO;AAClB,YAAW,SAAS;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,cAAa,SAAS;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,YAAW,aAAa;AACxB;AACA;AACA;AACA,+BAA8B;AAC9B;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,YAAW,SAAS;AACpB,YAAW,SAAS;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW,aAAa;AACxB,aAAY,oBAAoB;AAChC;;AAEA;AACA;AACA,cAAa,OAAO;AACpB;AACA;AACA;AACA;AACA,yDAAwD,UAAU,EAAE;AACpE;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,YAAW,QAAQ;AACnB;AACA;AACA;AACA;AACA,gDAA+C,iBAAiB;AAChE;AACA;AACA,aAAY;AACZ,gCAA+B,iBAAiB,EAAE;AAClD,QAAO,EAAE;AACT;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;;;;;;ACxVA,EAAC,8BAA8B;;AAE/B;AACA;AACA,aAAY;AACZ;;AAEA;;AAEA;AACA;AACA;AACA,qBAAoB;AACpB;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,iBAAgB,SAAS;AACzB,iBAAgB,WAAW;AAC3B,kBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA,kBAAiB,SAAS;AAC1B,kBAAiB,WAAW;AAC5B,kBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAA+B,oBAAoB;AACnD;AACA;AACA,YAAW;AACX;AACA;AACA,QAAO;AACP;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA,kBAAiB,SAAS;AAC1B,kBAAiB,WAAW;AAC5B,kBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA,kBAAiB,SAAS;AAC1B,kBAAiB,SAAS;AAC1B;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,oBAAmB,YAAY;AAC/B;AACA;;AAEA;;AAEA,oBAAmB,aAAa;AAChC;AACA;;AAEA;AACA;;AAEA;AACA,QAAO;AACP;AACA;AACA;AACA;AACA,IAAG;;AAEH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAuB,oBAAoB;AAC3C;AACA;;AAEA,EAAC,qD;;;;;;;;+CCpIkB,sB,EACE,sB;;6BADF,M,WACE,Q;;;;;;;;4BADjBF,I,EACAQ,M;;;;;;;;;;;;;;;;;;;;;;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","file":"router.js","sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory(require(\"riot\"));\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([\"riot\"], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"Router\"] = factory(require(\"riot\"));\n\telse\n\t\troot[\"Router\"] = factory(root[\"riot\"]);\n})(this, function(__WEBPACK_EXTERNAL_MODULE_1__) {\nreturn \n\n\n// WEBPACK FOOTER //\n// webpack/universalModuleDefinition"," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\texports: {},\n \t\t\tid: moduleId,\n \t\t\tloaded: false\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.loaded = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"/dist/\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(0);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap 56bfc5db8623b637755d","var riot = require('riot');\nvar route = require('riot-route');\nvar Router = require('./src/router.js');\nvar router = Router.create({route: route});\nif (window) {\n window.router = router;\n}\nmodule.exports = Router;\n\n\n\n\n// WEBPACK FOOTER //\n// ./router.js","module.exports = __WEBPACK_EXTERNAL_MODULE_1__;\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"riot\"\n// module id = 1\n// module chunks = 0 1","'use strict';\n\nfunction _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }\n\nvar observable = _interopDefault(require('riot-observable'));\n\n/**\n * Simple client-side router\n * @module riot-route\n */\n\nvar RE_ORIGIN = /^.+?\\/\\/+[^\\/]+/;\nvar EVENT_LISTENER = 'EventListener';\nvar REMOVE_EVENT_LISTENER = 'remove' + EVENT_LISTENER;\nvar ADD_EVENT_LISTENER = 'add' + EVENT_LISTENER;\nvar HAS_ATTRIBUTE = 'hasAttribute';\nvar POPSTATE = 'popstate';\nvar HASHCHANGE = 'hashchange';\nvar TRIGGER = 'trigger';\nvar MAX_EMIT_STACK_LEVEL = 3;\nvar win = typeof window != 'undefined' && window;\nvar doc = typeof document != 'undefined' && document;\nvar hist = win && history;\nvar loc = win && (hist.location || win.location);\nvar prot = Router.prototype;\nvar clickEvent = doc && doc.ontouchstart ? 'touchstart' : 'click';\nvar central = observable();\n\nvar started = false;\nvar routeFound = false;\nvar debouncedEmit;\nvar base;\nvar current;\nvar parser;\nvar secondParser;\nvar emitStack = [];\nvar emitStackLevel = 0;\n\n/**\n * Default parser. You can replace it via router.parser method.\n * @param {string} path - current path (normalized)\n * @returns {array} array\n */\nfunction DEFAULT_PARSER(path) {\n return path.split(/[/?#]/)\n}\n\n/**\n * Default parser (second). You can replace it via router.parser method.\n * @param {string} path - current path (normalized)\n * @param {string} filter - filter string (normalized)\n * @returns {array} array\n */\nfunction DEFAULT_SECOND_PARSER(path, filter) {\n var f = filter\n .replace(/\\?/g, '\\\\?')\n .replace(/\\*/g, '([^/?#]+?)')\n .replace(/\\.\\./, '.*');\n var re = new RegExp((\"^\" + f + \"$\"));\n var args = path.match(re);\n\n if (args) { return args.slice(1) }\n}\n\n/**\n * Simple/cheap debounce implementation\n * @param {function} fn - callback\n * @param {number} delay - delay in seconds\n * @returns {function} debounced function\n */\nfunction debounce(fn, delay) {\n var t;\n return function () {\n clearTimeout(t);\n t = setTimeout(fn, delay);\n }\n}\n\n/**\n * Set the window listeners to trigger the routes\n * @param {boolean} autoExec - see route.start\n */\nfunction start(autoExec) {\n debouncedEmit = debounce(emit, 1);\n win[ADD_EVENT_LISTENER](POPSTATE, debouncedEmit);\n win[ADD_EVENT_LISTENER](HASHCHANGE, debouncedEmit);\n doc[ADD_EVENT_LISTENER](clickEvent, click);\n if (autoExec) { emit(true); }\n}\n\n/**\n * Router class\n */\nfunction Router() {\n this.$ = [];\n observable(this); // make it observable\n central.on('stop', this.s.bind(this));\n central.on('emit', this.e.bind(this));\n}\n\nfunction normalize(path) {\n return path.replace(/^\\/|\\/$/, '')\n}\n\nfunction isString(str) {\n return typeof str == 'string'\n}\n\n/**\n * Get the part after domain name\n * @param {string} href - fullpath\n * @returns {string} path from root\n */\nfunction getPathFromRoot(href) {\n return (href || loc.href).replace(RE_ORIGIN, '')\n}\n\n/**\n * Get the part after base\n * @param {string} href - fullpath\n * @returns {string} path from base\n */\nfunction getPathFromBase(href) {\n return base[0] === '#'\n ? (href || loc.href || '').split(base)[1] || ''\n : (loc ? getPathFromRoot(href) : href || '').replace(base, '')\n}\n\nfunction emit(force) {\n // the stack is needed for redirections\n var isRoot = emitStackLevel === 0;\n if (MAX_EMIT_STACK_LEVEL <= emitStackLevel) { return }\n\n emitStackLevel++;\n emitStack.push(function() {\n var path = getPathFromBase();\n if (force || path !== current) {\n central[TRIGGER]('emit', path);\n current = path;\n }\n });\n if (isRoot) {\n var first;\n while (first = emitStack.shift()) { first(); } // stack increses within this call\n emitStackLevel = 0;\n }\n}\n\nfunction click(e) {\n if (\n e.which !== 1 // not left click\n || e.metaKey || e.ctrlKey || e.shiftKey // or meta keys\n || e.defaultPrevented // or default prevented\n ) { return }\n\n var el = e.target;\n while (el && el.nodeName !== 'A') { el = el.parentNode; }\n\n if (\n !el || el.nodeName !== 'A' // not A tag\n || el[HAS_ATTRIBUTE]('download') // has download attr\n || !el[HAS_ATTRIBUTE]('href') // has no href attr\n || el.target && el.target !== '_self' // another window or frame\n || el.href.indexOf(loc.href.match(RE_ORIGIN)[0]) === -1 // cross origin\n ) { return }\n\n if (el.href !== loc.href\n && (\n el.href.split('#')[0] === loc.href.split('#')[0] // internal jump\n || base[0] !== '#' && getPathFromRoot(el.href).indexOf(base) !== 0 // outside of base\n || base[0] === '#' && el.href.split(base)[0] !== loc.href.split(base)[0] // outside of #base\n || !go(getPathFromBase(el.href), el.title || doc.title) // route not found\n )) { return }\n\n e.preventDefault();\n}\n\n/**\n * Go to the path\n * @param {string} path - destination path\n * @param {string} title - page title\n * @param {boolean} shouldReplace - use replaceState or pushState\n * @returns {boolean} - route not found flag\n */\nfunction go(path, title, shouldReplace) {\n // Server-side usage: directly execute handlers for the path\n if (!hist) { return central[TRIGGER]('emit', getPathFromBase(path)) }\n\n path = base + normalize(path);\n title = title || doc.title;\n // browsers ignores the second parameter `title`\n shouldReplace\n ? hist.replaceState(null, title, path)\n : hist.pushState(null, title, path);\n // so we need to set it manually\n doc.title = title;\n routeFound = false;\n emit();\n return routeFound\n}\n\n/**\n * Go to path or set action\n * a single string: go there\n * two strings: go there with setting a title\n * two strings and boolean: replace history with setting a title\n * a single function: set an action on the default route\n * a string/RegExp and a function: set an action on the route\n * @param {(string|function)} first - path / action / filter\n * @param {(string|RegExp|function)} second - title / action\n * @param {boolean} third - replace flag\n */\nprot.m = function(first, second, third) {\n if (isString(first) && (!second || isString(second))) { go(first, second, third || false); }\n else if (second) { this.r(first, second); }\n else { this.r('@', first); }\n};\n\n/**\n * Stop routing\n */\nprot.s = function() {\n this.off('*');\n this.$ = [];\n};\n\n/**\n * Emit\n * @param {string} path - path\n */\nprot.e = function(path) {\n this.$.concat('@').some(function(filter) {\n var args = (filter === '@' ? parser : secondParser)(normalize(path), normalize(filter));\n if (typeof args != 'undefined') {\n this[TRIGGER].apply(null, [filter].concat(args));\n return routeFound = true // exit from loop\n }\n }, this);\n};\n\n/**\n * Register route\n * @param {string} filter - filter for matching to url\n * @param {function} action - action to register\n */\nprot.r = function(filter, action) {\n if (filter !== '@') {\n filter = '/' + normalize(filter);\n this.$.push(filter);\n }\n this.on(filter, action);\n};\n\nvar mainRouter = new Router();\nvar route = mainRouter.m.bind(mainRouter);\n\n/**\n * Create a sub router\n * @returns {function} the method of a new Router object\n */\nroute.create = function() {\n var newSubRouter = new Router();\n // assign sub-router's main method\n var router = newSubRouter.m.bind(newSubRouter);\n // stop only this sub-router\n router.stop = newSubRouter.s.bind(newSubRouter);\n return router\n};\n\n/**\n * Set the base of url\n * @param {(str|RegExp)} arg - a new base or '#' or '#!'\n */\nroute.base = function(arg) {\n base = arg || '#';\n current = getPathFromBase(); // recalculate current path\n};\n\n/** Exec routing right now **/\nroute.exec = function() {\n emit(true);\n};\n\n/**\n * Replace the default router to yours\n * @param {function} fn - your parser function\n * @param {function} fn2 - your secondParser function\n */\nroute.parser = function(fn, fn2) {\n if (!fn && !fn2) {\n // reset parser for testing...\n parser = DEFAULT_PARSER;\n secondParser = DEFAULT_SECOND_PARSER;\n }\n if (fn) { parser = fn; }\n if (fn2) { secondParser = fn2; }\n};\n\n/**\n * Helper function to get url query as an object\n * @returns {object} parsed query\n */\nroute.query = function() {\n var q = {};\n var href = loc.href || current;\n href.replace(/[?&](.+?)=([^&]*)/g, function(_, k, v) { q[k] = v; });\n return q\n};\n\n/** Stop routing **/\nroute.stop = function () {\n if (started) {\n if (win) {\n win[REMOVE_EVENT_LISTENER](POPSTATE, debouncedEmit);\n win[REMOVE_EVENT_LISTENER](HASHCHANGE, debouncedEmit);\n doc[REMOVE_EVENT_LISTENER](clickEvent, click);\n }\n central[TRIGGER]('stop');\n started = false;\n }\n};\n\n/**\n * Start routing\n * @param {boolean} autoExec - automatically exec after starting if true\n */\nroute.start = function (autoExec) {\n if (!started) {\n if (win) {\n if (document.readyState === 'complete') { start(autoExec); }\n // the timeout is needed to solve\n // a weird safari bug https://github.com/riot/route/issues/33\n else { win[ADD_EVENT_LISTENER]('load', function() {\n setTimeout(function() { start(autoExec); }, 1);\n }); }\n }\n started = true;\n }\n};\n\n/** Prepare the router **/\nroute.base();\nroute.parser();\n\nmodule.exports = route;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/riot-route/dist/cjs.route.js\n// module id = 2\n// module chunks = 0",";(function(window, undefined) {var observable = function(el) {\n\n /**\n * Extend the original object or create a new empty one\n * @type { Object }\n */\n\n el = el || {}\n\n /**\n * Private variables\n */\n var callbacks = {},\n slice = Array.prototype.slice\n\n /**\n * Public Api\n */\n\n // extend the el object adding the observable methods\n Object.defineProperties(el, {\n /**\n * Listen to the given `event` ands\n * execute the `callback` each time an event is triggered.\n * @param { String } event - event id\n * @param { Function } fn - callback function\n * @returns { Object } el\n */\n on: {\n value: function(event, fn) {\n if (typeof fn == 'function')\n (callbacks[event] = callbacks[event] || []).push(fn)\n return el\n },\n enumerable: false,\n writable: false,\n configurable: false\n },\n\n /**\n * Removes the given `event` listeners\n * @param { String } event - event id\n * @param { Function } fn - callback function\n * @returns { Object } el\n */\n off: {\n value: function(event, fn) {\n if (event == '*' && !fn) callbacks = {}\n else {\n if (fn) {\n var arr = callbacks[event]\n for (var i = 0, cb; cb = arr && arr[i]; ++i) {\n if (cb == fn) arr.splice(i--, 1)\n }\n } else delete callbacks[event]\n }\n return el\n },\n enumerable: false,\n writable: false,\n configurable: false\n },\n\n /**\n * Listen to the given `event` and\n * execute the `callback` at most once\n * @param { String } event - event id\n * @param { Function } fn - callback function\n * @returns { Object } el\n */\n one: {\n value: function(event, fn) {\n function on() {\n el.off(event, on)\n fn.apply(el, arguments)\n }\n return el.on(event, on)\n },\n enumerable: false,\n writable: false,\n configurable: false\n },\n\n /**\n * Execute all callback functions that listen to\n * the given `event`\n * @param { String } event - event id\n * @returns { Object } el\n */\n trigger: {\n value: function(event) {\n\n // getting the arguments\n var arglen = arguments.length - 1,\n args = new Array(arglen),\n fns,\n fn,\n i\n\n for (i = 0; i < arglen; i++) {\n args[i] = arguments[i + 1] // skip first argument\n }\n\n fns = slice.call(callbacks[event] || [], 0)\n\n for (i = 0; fn = fns[i]; ++i) {\n fn.apply(el, args)\n }\n\n if (callbacks['*'] && event != '*')\n el.trigger.apply(el, ['*', event].concat(args))\n\n return el\n },\n enumerable: false,\n writable: false,\n configurable: false\n }\n })\n\n return el\n\n}\n /* istanbul ignore next */\n // support CommonJS, AMD & browser\n if (typeof exports === 'object')\n module.exports = observable\n else if (typeof define === 'function' && define.amd)\n define(function() { return observable })\n else\n window.observable = observable\n\n})(typeof window != 'undefined' ? window : undefined);\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/riot-observable/dist/observable.js\n// module id = 3\n// module chunks = 0","var riot = require('riot');\nvar extend = require('extend');\nvar error = console && console.error || function () {};\n\nclass Router {\n constructor() {\n riot.observable(this);\n this.interceptors = [this.processRoute.bind(this)];\n this.handler = new InitialRoute();\n this.current = new Context(\"\").response;\n this.process = this.process.bind(this);\n }\n\n route(handler) {\n this.handler = handler;\n }\n\n routes(routes) {\n this.route(new InitialRoute().routes(routes));\n }\n\n use(interceptor) {\n this.interceptors.push(interceptor);\n }\n\n process() {\n var params = Array.prototype.slice.call(arguments);\n var query = {};\n var uri = params.filter(function (p) {\n if (typeof (p) !== 'string') {\n query = p;\n return false;\n }\n return true;\n }).join(\"/\");\n if (uri[0] !== '/') uri = \"/\" + uri; // handle '#any' as '#/any'\n var context = new Context(new Request(uri, query));\n if (!this.rootContext) this.rootContext = context;\n this.processRequest(context);\n return context;\n }\n\n processRequest(context) {\n this.processInterceptors(context);\n return this.processResponse(context);\n }\n\n processResponse(context) {\n if (this.isRedirect(context)) {\n return this.processRedirect(context);\n }\n var {\n request,\n response\n } = context;\n if (!response.redirectTo) {\n this.current = response;\n this.rootContext = null;\n this.trigger('route:updated', response);\n return context;\n }\n }\n\n isRedirect(context) {\n return !!context.response.redirectTo;\n }\n\n processRedirect(context) {\n var uri = context.response.redirectTo;\n this.rootContext.addRedirect(uri);\n this.navigateTo(uri);\n }\n\n navigateTo() {\n var args = Array.prototype.slice.call(arguments);\n if (typeof(args[1]) === 'boolean') {\n args.splice(1, 0, '');\n }\n this.config.route.apply(null, args);\n }\n\n processInterceptors(context, preInterceptors, postInterceptors) {\n var interceptors = (preInterceptors || []).concat(this.interceptors).concat(postInterceptors || []);\n var next = function next() {\n if (!context.stop) {\n var processor = interceptors.shift();\n var {\n request,\n response\n } = context;\n if (processor)\n return processor(request, response, next, context);\n }\n return context;\n };\n return next();\n }\n\n processRoute(request, response, next, context) {\n this.handler.process(request, response, context);\n return next();\n }\n\n start() {\n this.config.route.start();\n this.exec();\n }\n\n exec() {\n this.config.route.exec(this.process);\n }\n\n configure(options) {\n this.config = extend(true, {}, this.config, options);\n if (this.config.route.parser && this.config.parser)\n this.config.route.parser(this.config.parser);\n if (this.config.route.base && this.config.base)\n this.config.route.base(this.config.base);\n this.config.route(this.process);\n }\n\n}\n\nclass Context {\n constructor(request) {\n this.request = typeof (request) === 'string' ? new Request(request) : request;\n this.response = new Response(this.request);\n this.redirectStack = [];\n }\n\n addRedirect(uri) {\n if (this.redirectStack.indexOf(uri) > -1)\n throw new Error(\"Cyclic redirection to \" + uri + \". Stack = \" + this.redirectStack);\n this.redirectStack.push(uri);\n }\n\n}\n\nclass Handler {\n constructor() {}\n\n matches(request) {\n return false;\n }\n\n process(request, response) {\n var matcher = this.matches(request);\n if (!matcher) return this.routeMiss(request, response);\n return this.routeMatch(request, response, matcher);\n }\n\n routeMatch(request, response, matcher) {\n response.add(matcher);\n return true;\n }\n\n routeMiss(request, response) {\n return false;\n }\n\n processRoutes(request, response, routes) {\n if (routes && routes.length) {\n var t = routes.length;\n for (var i = 0; i < t; i++) {\n var route = routes[i];\n if (route.process(request, response))\n return true;\n }\n return false;\n }\n }\n\n createRequest(request, matcher) {\n return new ChildRequest(request, matcher);\n }\n}\n\nclass Route extends Handler {\n constructor(options) {\n super(options);\n options = options || {};\n this.tag = options.tag;\n this.api = options.api;\n this.path = options.path;\n this.name = options.name;\n this.updatable = options.updatable;\n this.pathParameterNames = [];\n var path = this.getPath().replace(/^\\//, \"\");\n this.pattern = \"^/?\" + path.replace(/:([^/]+)/g, function (ignored, group) {\n this.pathParameterNames.push(group);\n return \"([^/]+)\";\n }.bind(this)) + \"(:?/|$)\";\n this.regex = new RegExp(this.pattern);\n }\n\n routes(routes) {\n var redirectRoutes = routes.filter(function (r) {\n return r instanceof RedirectRoute;\n });\n var defaultRoutes = routes.filter(function (r) {\n return r instanceof DefaultRoute;\n });\n var notFoundRoutes = routes.filter(function (r) {\n return r instanceof NotFoundRoute;\n });\n var otherRoutes = routes.filter(function (r) {\n return redirectRoutes.indexOf(r) === -1 &&\n defaultRoutes.indexOf(r) === -1 &&\n notFoundRoutes.indexOf(r) === -1;\n });\n if (notFoundRoutes.length > 1) error(\"Can't use more than one NotFoundRoute per route. --> \" + this.getPath());\n if (defaultRoutes.length > 1) error(\"Can't use more than one DefaultRoute per route. --> \" + this.getPath());\n this._routes = [].concat(redirectRoutes).concat(otherRoutes).concat(defaultRoutes).concat(notFoundRoutes);\n return this;\n }\n\n matches(request) {\n var matcher = this.regex.exec(request.uri);\n if (matcher) {\n var params = {};\n for (var i in this.pathParameterNames) {\n if (this.pathParameterNames.hasOwnProperty(i)) {\n var name = this.pathParameterNames[i];\n params[name] = decodeURIComponent(matcher[parseInt(i, 10) + 1]);\n }\n }\n return {\n route: this,\n tag: this.tag,\n api: this.api,\n found: matcher[0],\n params: params\n };\n }\n return false;\n }\n\n routeMatch(request, response, matcher) {\n var matches = super.routeMatch(request, response, matcher);\n this.processRoutes(request, response, matcher);\n return matches;\n }\n\n processRoutes(request, response, matcher) {\n return super.processRoutes(this.createRequest(request, matcher), response, this._routes);\n }\n\n getPath() {\n return this.name || this.path || (typeof this.tag === 'string' ? this.tag : '');\n }\n}\n\nclass InitialRoute extends Route {\n\n}\n\nclass ChildRequest {\n constructor(request, matcher) {\n this.request = request;\n this.matcher = matcher;\n this.uri = this.request.uri.substring(matcher.found.length);\n this.parentUri = this.request.uri.substring(0, matcher.found.length);\n this.query = this.request.query;\n }\n}\n\nclass NotFoundRoute extends Handler {\n constructor(options) {\n super(options);\n options = options || {};\n this.tag = options.tag;\n this.api = options.api;\n }\n matches(request) {\n return {\n route: this,\n tag: this.tag,\n api: this.api,\n found: request.uri\n };\n }\n}\n\nclass RedirectRoute extends Handler {\n constructor(options) {\n super(options);\n options = options || {};\n this.from = options.from;\n this.to = options.to;\n this.pattern = \"(^/?)\" + this.from + \"(/|$)\";\n this.regex = new RegExp(this.pattern);\n }\n\n process(request, response) {\n var uri = request.uri.replace(this.regex, \"$1\" + this.to + \"$2\");\n if (uri !== request.uri) {\n var parent = request.parentUri || \"\";\n response.redirectTo = parent + uri;\n return true;\n }\n }\n\n}\n\nclass DefaultRoute extends Handler {\n constructor(options) {\n super(options);\n options = options || {};\n this.tag = options.tag;\n this.api = options.api;\n }\n matches(request) {\n var uri = request.uri.trim();\n if (uri === \"/\" || uri === \"\")\n return {\n route: this,\n tag: this.tag,\n api: this.api,\n found: uri\n };\n }\n}\n\nclass Request {\n constructor(uri, query) {\n this.uri = uri;\n this.query = query;\n }\n}\n\nclass Response {\n constructor(request) {\n this.uri = request.uri;\n this.matches = [];\n this.params = {};\n this.query = request.query;\n }\n add(matcher) {\n this.matches.push(matcher);\n var params = matcher.params;\n if (params) {\n for (var key in params) {\n if (params.hasOwnProperty(key)) {\n this.params[key] = params[key];\n }\n }\n }\n }\n\n get(index) {\n return this.matches[index];\n }\n\n size() {\n return this.matches.length;\n }\n\n isEmpty() {\n return this.matches.length;\n }\n\n}\n\nfunction registerTag(router) {\n riot.tag('route', '', '', '', function (opts) {\n this.calculateLevel = function (target) {\n var level = 0;\n if (target.parent) level += this.calculateLevel(target.parent);\n if (target.opts.__router_level) level += target.opts.__router_level;\n if (target.__router_tag) level += 1;\n return level;\n }.bind(this);\n\n this.normalizeTag = function (tag, api, options) {\n var result = tag(api, options);\n if (typeof result === 'string') {\n tag = result;\n } else {\n tag = result.tag || tag;\n api = result.api || api;\n }\n return [tag, api, options];\n }\n\n this.unmountTag = function () {\n if (this.instance)\n this.instance.unmount(true);\n }\n\n this.mountTag = function (tag, api, options) {\n if (typeof tag === 'function') {\n [tag, api, options] = this.normalizeTag(tag, api, options);\n }\n if (this.canUpdate(tag, api, options)) {\n this.instance.update(api);\n } else {\n this.unmountTag();\n if (tag) {\n this.root.replaceChild(document.createElement(tag), this.root.children[0]);\n try {\n this.instance = riot.mount(this.root.children[0], tag, api)[0];\n } catch (e) {\n error(\"Error when mounting tag '\" + tag + \"'.\", e);\n return;\n }\n this.instanceTag = tag;\n this.instanceApi = api;\n }\n }\n }\n\n this.canUpdate = function (tag, api, options) {\n if ((!router.config.updatable && !opts.updatable && !options.updatable) ||\n !this.instance ||\n !this.instance.isMounted ||\n this.instanceTag !== tag)\n return false;\n return true;\n }\n\n this.updateRoute = function () {\n var mount = {\n tag: null\n };\n if (router && router.current) {\n var response = router.current;\n if (this.level <= response.size()) {\n var matcher = response.get(this.level);\n if (matcher) {\n var params = matcher.params || {};\n var query = response.query || {};\n var api = extend(true, {}, opts, query, matcher.api, params, {\n __router_level: this.level,\n query: query\n });\n mount = {\n tag: matcher.tag,\n api: api,\n updatable: matcher.route.updatable\n };\n }\n }\n }\n if (mount.tag)\n this.mountTag(mount.tag, mount.api, mount);\n else\n this.unmountTag();\n }.bind(this);\n\n this.__router_tag = 'route';\n this.level = this.calculateLevel(this);\n router.on('route:updated', this.updateRoute);\n this.on('unmount', function () {\n router.off('route:updated', this.updateRoute);\n this.unmountTag();\n }.bind(this));\n this.on('mount', this.updateRoute);\n });\n}\n\nfunction detectRoute() {\n var route = riot.route ||\n (window && window.route) ||\n (global && global.route);\n return route;\n}\n\nfunction create(config) {\n var router = new Router();\n router.configure(extend(true, {\n updatable: true,\n route: detectRoute(),\n base: '#',\n parser: function customRiotParser(path) {\n var raw = path.split('?'),\n uri = raw[0].split('/'),\n query = raw[1],\n params = {}\n if (query) {\n query.split('&').forEach(function (v) {\n var c = v.split('=')\n params[c[0]] = c[1]\n })\n }\n uri.push(params)\n return uri\n }\n }, config));\n registerTag(router);\n if (!Router.instance) Router.instance = router;\n return router;\n}\nRouter.create = create;\nRouter.Route = Route;\nRouter.DefaultRoute = DefaultRoute;\nRouter.RedirectRoute = RedirectRoute;\nRouter.NotFoundRoute = NotFoundRoute;\nRouter._ = {\n Response: Response,\n Request: Request\n};\nmodule.exports = Router;\n\n\n\n// WEBPACK FOOTER //\n// ./src/router.js","'use strict';\n\nvar hasOwn = Object.prototype.hasOwnProperty;\nvar toStr = Object.prototype.toString;\n\nvar isArray = function isArray(arr) {\n\tif (typeof Array.isArray === 'function') {\n\t\treturn Array.isArray(arr);\n\t}\n\n\treturn toStr.call(arr) === '[object Array]';\n};\n\nvar isPlainObject = function isPlainObject(obj) {\n\tif (!obj || toStr.call(obj) !== '[object Object]') {\n\t\treturn false;\n\t}\n\n\tvar hasOwnConstructor = hasOwn.call(obj, 'constructor');\n\tvar hasIsPrototypeOf = obj.constructor && obj.constructor.prototype && hasOwn.call(obj.constructor.prototype, 'isPrototypeOf');\n\t// Not own constructor property must be Object\n\tif (obj.constructor && !hasOwnConstructor && !hasIsPrototypeOf) {\n\t\treturn false;\n\t}\n\n\t// Own properties are enumerated firstly, so to speed up,\n\t// if last one is own, then all properties are own.\n\tvar key;\n\tfor (key in obj) {/**/}\n\n\treturn typeof key === 'undefined' || hasOwn.call(obj, key);\n};\n\nmodule.exports = function extend() {\n\tvar options, name, src, copy, copyIsArray, clone,\n\t\ttarget = arguments[0],\n\t\ti = 1,\n\t\tlength = arguments.length,\n\t\tdeep = false;\n\n\t// Handle a deep copy situation\n\tif (typeof target === 'boolean') {\n\t\tdeep = target;\n\t\ttarget = arguments[1] || {};\n\t\t// skip the boolean and the target\n\t\ti = 2;\n\t} else if ((typeof target !== 'object' && typeof target !== 'function') || target == null) {\n\t\ttarget = {};\n\t}\n\n\tfor (; i < length; ++i) {\n\t\toptions = arguments[i];\n\t\t// Only deal with non-null/undefined values\n\t\tif (options != null) {\n\t\t\t// Extend the base object\n\t\t\tfor (name in options) {\n\t\t\t\tsrc = target[name];\n\t\t\t\tcopy = options[name];\n\n\t\t\t\t// Prevent never-ending loop\n\t\t\t\tif (target !== copy) {\n\t\t\t\t\t// Recurse if we're merging plain objects or arrays\n\t\t\t\t\tif (deep && copy && (isPlainObject(copy) || (copyIsArray = isArray(copy)))) {\n\t\t\t\t\t\tif (copyIsArray) {\n\t\t\t\t\t\t\tcopyIsArray = false;\n\t\t\t\t\t\t\tclone = src && isArray(src) ? src : [];\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tclone = src && isPlainObject(src) ? src : {};\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Never move original objects, clone them\n\t\t\t\t\t\ttarget[name] = extend(deep, clone, copy);\n\n\t\t\t\t\t// Don't bring in undefined values\n\t\t\t\t\t} else if (typeof copy !== 'undefined') {\n\t\t\t\t\t\ttarget[name] = copy;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Return the modified object\n\treturn target;\n};\n\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/extend/index.js\n// module id = 5\n// module chunks = 0 1"],"sourceRoot":""} --------------------------------------------------------------------------------