UNPKG

vue-router

Version:
1,761 lines (1,438 loc) 80.9 kB
/*! * vue-router v0.6.1 * (c) 2015 Evan You * Released under the MIT License. */ (function webpackUniversalModuleDefinition(root, factory) { if(typeof exports === 'object' && typeof module === 'object') module.exports = factory(); else if(typeof define === 'function' && define.amd) define([], factory); else if(typeof exports === 'object') exports["VueRouter"] = factory(); else root["VueRouter"] = factory(); })(this, function() { return /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ // Check if module is in cache /******/ if(installedModules[moduleId]) /******/ return installedModules[moduleId].exports; /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ exports: {}, /******/ id: moduleId, /******/ loaded: false /******/ }; /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ // Flag the module as loaded /******/ module.loaded = true; /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ // __webpack_public_path__ /******/ __webpack_require__.p = ""; /******/ // Load entry module and return exports /******/ return __webpack_require__(0); /******/ }) /************************************************************************/ /******/ ([ /* 0 */ /***/ function(module, exports, __webpack_require__) { 'use strict'; var _classCallCheck = __webpack_require__(1)['default']; var _interopRequireDefault = __webpack_require__(2)['default']; Object.defineProperty(exports, '__esModule', { value: true }); var _util = __webpack_require__(3); var _util2 = _interopRequireDefault(_util); var _routeRecognizer = __webpack_require__(4); var _routeRecognizer2 = _interopRequireDefault(_routeRecognizer); var _routerApi = __webpack_require__(7); var _routerApi2 = _interopRequireDefault(_routerApi); var _routerInternal = __webpack_require__(8); var _routerInternal2 = _interopRequireDefault(_routerInternal); var _directivesView = __webpack_require__(26); var _directivesView2 = _interopRequireDefault(_directivesView); var _directivesLink = __webpack_require__(27); var _directivesLink2 = _interopRequireDefault(_directivesLink); var _override = __webpack_require__(28); var _override2 = _interopRequireDefault(_override); var _historyAbstract = __webpack_require__(29); var _historyAbstract2 = _interopRequireDefault(_historyAbstract); var _historyHash = __webpack_require__(30); var _historyHash2 = _interopRequireDefault(_historyHash); var _historyHtml5 = __webpack_require__(31); var _historyHtml52 = _interopRequireDefault(_historyHtml5); var historyBackends = { abstract: _historyAbstract2['default'], hash: _historyHash2['default'], html5: _historyHtml52['default'] }; /** * Router constructor * * @param {Object} [options] */ var Router = function Router() { var _ref = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; var _ref$hashbang = _ref.hashbang; var hashbang = _ref$hashbang === undefined ? true : _ref$hashbang; var _ref$abstract = _ref.abstract; var abstract = _ref$abstract === undefined ? false : _ref$abstract; var _ref$history = _ref.history; var history = _ref$history === undefined ? false : _ref$history; var _ref$saveScrollPosition = _ref.saveScrollPosition; var saveScrollPosition = _ref$saveScrollPosition === undefined ? false : _ref$saveScrollPosition; var _ref$transitionOnLoad = _ref.transitionOnLoad; var transitionOnLoad = _ref$transitionOnLoad === undefined ? false : _ref$transitionOnLoad; var _ref$suppressTransitionError = _ref.suppressTransitionError; var suppressTransitionError = _ref$suppressTransitionError === undefined ? false : _ref$suppressTransitionError; var _ref$root = _ref.root; var root = _ref$root === undefined ? null : _ref$root; var _ref$linkActiveClass = _ref.linkActiveClass; var linkActiveClass = _ref$linkActiveClass === undefined ? 'v-link-active' : _ref$linkActiveClass; _classCallCheck(this, Router); /* istanbul ignore if */ if (!Router.installed) { throw new Error('Please install the Router with Vue.use() before ' + 'creating an instance.'); } // Vue instances this.app = null; this._views = []; this._children = []; // route recognizer this._recognizer = new _routeRecognizer2['default'](); this._guardRecognizer = new _routeRecognizer2['default'](); // state this._started = false; this._currentRoute = {}; this._currentTransition = null; this._previousTransition = null; this._notFoundHandler = null; this._beforeEachHooks = []; this._afterEachHooks = []; // feature detection this._hasPushState = typeof window !== 'undefined' && window.history && window.history.pushState; // trigger transition on initial render? this._rendered = false; this._transitionOnLoad = transitionOnLoad; // history mode this._abstract = abstract; this._hashbang = hashbang; this._history = this._hasPushState && history; // other options this._saveScrollPosition = saveScrollPosition; this._linkActiveClass = linkActiveClass; this._suppress = suppressTransitionError; // create history object var inBrowser = _util2['default'].Vue.util.inBrowser; this.mode = !inBrowser || this._abstract ? 'abstract' : this._history ? 'html5' : 'hash'; var History = historyBackends[this.mode]; var self = this; this.history = new History({ root: root, hashbang: this._hashbang, onChange: function onChange(path, state, anchor) { self._match(path, state, anchor); } }); }; exports['default'] = Router; Router.installed = false; /** * Installation interface. * Install the necessary directives. */ Router.install = function (Vue) { /* istanbul ignore if */ if (Router.installed) { (0, _util.warn)('already installed.'); return; } (0, _routerApi2['default'])(Vue, Router); (0, _routerInternal2['default'])(Vue, Router); (0, _directivesView2['default'])(Vue); (0, _directivesLink2['default'])(Vue); (0, _override2['default'])(Vue); _util2['default'].Vue = Vue; // 1.0 only: enable route mixins var strats = Vue.config.optionMergeStrategies; if (strats) { // use the same merge strategy as methods (object hash) strats.route = strats.methods; } Router.installed = true; }; // auto install /* istanbul ignore if */ if (typeof window !== 'undefined' && window.Vue) { window.Vue.use(Router); } module.exports = exports['default']; /***/ }, /* 1 */ /***/ function(module, exports) { "use strict"; exports["default"] = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; exports.__esModule = true; /***/ }, /* 2 */ /***/ function(module, exports) { "use strict"; exports["default"] = function (obj) { return obj && obj.__esModule ? obj : { "default": obj }; }; exports.__esModule = true; /***/ }, /* 3 */ /***/ function(module, exports, __webpack_require__) { 'use strict'; var _interopRequireDefault = __webpack_require__(2)['default']; Object.defineProperty(exports, '__esModule', { value: true }); exports.warn = warn; exports.resolvePath = resolvePath; exports.isPromise = isPromise; exports.getRouteConfig = getRouteConfig; exports.resolveAsyncComponent = resolveAsyncComponent; exports.mapParams = mapParams; var _routeRecognizer = __webpack_require__(4); var _routeRecognizer2 = _interopRequireDefault(_routeRecognizer); var genQuery = _routeRecognizer2['default'].prototype.generateQueryString; // export default for holding the Vue reference var _exports = {}; exports['default'] = _exports; /** * Warn stuff. * * @param {String} msg * @param {Error} [err] */ function warn(msg, err) { /* istanbul ignore next */ if (window.console) { console.warn('[vue-router] ' + msg); if (err) { console.warn(err.stack); } } } /** * Resolve a relative path. * * @param {String} base * @param {String} relative * @return {String} */ function resolvePath(base, relative) { var query = base.match(/(\?.*)$/); if (query) { query = query[1]; base = base.slice(0, -query.length); } // a query! if (relative.charAt(0) === '?') { return base + relative; } var stack = base.split('/'); // remove trailing segment stack.pop(); // resolve relative path var segments = relative.split('/'); for (var i = 0; i < segments.length; i++) { var segment = segments[i]; if (segment === '.') { continue; } else if (segment === '..') { stack.pop(); } else { stack.push(segment); } } // ensure leading slash if (stack[0] !== '') { stack.unshift(''); } return stack.join('/'); } /** * Forgiving check for a promise * * @param {Object} p * @return {Boolean} */ function isPromise(p) { return p && typeof p.then === 'function'; } /** * Retrive a route config field from a component instance * OR a component contructor. * * @param {Function|Vue} component * @param {String} name * @return {*} */ function getRouteConfig(component, name) { var options = component && (component.$options || component.options); return options && options.route && options.route[name]; } /** * Resolve an async component factory. Have to do a dirty * mock here because of Vue core's internal API depends on * an ID check. * * @param {Object} handler * @param {Function} cb */ var resolver = undefined; function resolveAsyncComponent(handler, cb) { if (!resolver) { resolver = { resolve: _exports.Vue.prototype._resolveComponent, $options: { components: { _: handler.component } } }; } else { resolver.$options.components._ = handler.component; } resolver.resolve('_', function (Component) { handler.component = Component; cb(Component); }); } /** * Map the dynamic segments in a path to params. * * @param {String} path * @param {Object} params * @param {Object} query */ function mapParams(path, params, query) { for (var key in params) { path = replaceParam(path, params, key); } if (query) { path += genQuery(query); } return path; } /** * Replace a param segment with real value in a matched * path. * * @param {String} path * @param {Object} params * @param {String} key * @return {String} */ function replaceParam(path, params, key) { var regex = new RegExp(':' + key + '(\\/|$)'); var value = params[key]; return path.replace(regex, function (m) { return m.charAt(m.length - 1) === '/' ? value + '/' : value; }); } /***/ }, /* 4 */ /***/ function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_RESULT__;/* WEBPACK VAR INJECTION */(function(module) {(function() { "use strict"; function $$route$recognizer$dsl$$Target(path, matcher, delegate) { this.path = path; this.matcher = matcher; this.delegate = delegate; } $$route$recognizer$dsl$$Target.prototype = { to: function(target, callback) { var delegate = this.delegate; if (delegate && delegate.willAddRoute) { target = delegate.willAddRoute(this.matcher.target, target); } this.matcher.add(this.path, target); if (callback) { if (callback.length === 0) { throw new Error("You must have an argument in the function passed to `to`"); } this.matcher.addChild(this.path, target, callback, this.delegate); } return this; } }; function $$route$recognizer$dsl$$Matcher(target) { this.routes = {}; this.children = {}; this.target = target; } $$route$recognizer$dsl$$Matcher.prototype = { add: function(path, handler) { this.routes[path] = handler; }, addChild: function(path, target, callback, delegate) { var matcher = new $$route$recognizer$dsl$$Matcher(target); this.children[path] = matcher; var match = $$route$recognizer$dsl$$generateMatch(path, matcher, delegate); if (delegate && delegate.contextEntered) { delegate.contextEntered(target, match); } callback(match); } }; function $$route$recognizer$dsl$$generateMatch(startingPath, matcher, delegate) { return function(path, nestedCallback) { var fullPath = startingPath + path; if (nestedCallback) { nestedCallback($$route$recognizer$dsl$$generateMatch(fullPath, matcher, delegate)); } else { return new $$route$recognizer$dsl$$Target(startingPath + path, matcher, delegate); } }; } function $$route$recognizer$dsl$$addRoute(routeArray, path, handler) { var len = 0; for (var i=0, l=routeArray.length; i<l; i++) { len += routeArray[i].path.length; } path = path.substr(len); var route = { path: path, handler: handler }; routeArray.push(route); } function $$route$recognizer$dsl$$eachRoute(baseRoute, matcher, callback, binding) { var routes = matcher.routes; for (var path in routes) { if (routes.hasOwnProperty(path)) { var routeArray = baseRoute.slice(); $$route$recognizer$dsl$$addRoute(routeArray, path, routes[path]); if (matcher.children[path]) { $$route$recognizer$dsl$$eachRoute(routeArray, matcher.children[path], callback, binding); } else { callback.call(binding, routeArray); } } } } var $$route$recognizer$dsl$$default = function(callback, addRouteCallback) { var matcher = new $$route$recognizer$dsl$$Matcher(); callback($$route$recognizer$dsl$$generateMatch("", matcher, this.delegate)); $$route$recognizer$dsl$$eachRoute([], matcher, function(route) { if (addRouteCallback) { addRouteCallback(this, route); } else { this.add(route); } }, this); }; var $$route$recognizer$$specials = [ '/', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '\\' ]; var $$route$recognizer$$escapeRegex = new RegExp('(\\' + $$route$recognizer$$specials.join('|\\') + ')', 'g'); function $$route$recognizer$$isArray(test) { return Object.prototype.toString.call(test) === "[object Array]"; } // A Segment represents a segment in the original route description. // Each Segment type provides an `eachChar` and `regex` method. // // The `eachChar` method invokes the callback with one or more character // specifications. A character specification consumes one or more input // characters. // // The `regex` method returns a regex fragment for the segment. If the // segment is a dynamic of star segment, the regex fragment also includes // a capture. // // A character specification contains: // // * `validChars`: a String with a list of all valid characters, or // * `invalidChars`: a String with a list of all invalid characters // * `repeat`: true if the character specification can repeat function $$route$recognizer$$StaticSegment(string) { this.string = string; } $$route$recognizer$$StaticSegment.prototype = { eachChar: function(callback) { var string = this.string, ch; for (var i=0, l=string.length; i<l; i++) { ch = string.charAt(i); callback({ validChars: ch }); } }, regex: function() { return this.string.replace($$route$recognizer$$escapeRegex, '\\$1'); }, generate: function() { return this.string; } }; function $$route$recognizer$$DynamicSegment(name) { this.name = name; } $$route$recognizer$$DynamicSegment.prototype = { eachChar: function(callback) { callback({ invalidChars: "/", repeat: true }); }, regex: function() { return "([^/]+)"; }, generate: function(params) { return params[this.name]; } }; function $$route$recognizer$$StarSegment(name) { this.name = name; } $$route$recognizer$$StarSegment.prototype = { eachChar: function(callback) { callback({ invalidChars: "", repeat: true }); }, regex: function() { return "(.+)"; }, generate: function(params) { return params[this.name]; } }; function $$route$recognizer$$EpsilonSegment() {} $$route$recognizer$$EpsilonSegment.prototype = { eachChar: function() {}, regex: function() { return ""; }, generate: function() { return ""; } }; function $$route$recognizer$$parse(route, names, specificity) { // normalize route as not starting with a "/". Recognition will // also normalize. if (route.charAt(0) === "/") { route = route.substr(1); } var segments = route.split("/"), results = []; // A routes has specificity determined by the order that its different segments // appear in. This system mirrors how the magnitude of numbers written as strings // works. // Consider a number written as: "abc". An example would be "200". Any other number written // "xyz" will be smaller than "abc" so long as `a > z`. For instance, "199" is smaller // then "200", even though "y" and "z" (which are both 9) are larger than "0" (the value // of (`b` and `c`). This is because the leading symbol, "2", is larger than the other // leading symbol, "1". // The rule is that symbols to the left carry more weight than symbols to the right // when a number is written out as a string. In the above strings, the leading digit // represents how many 100's are in the number, and it carries more weight than the middle // number which represents how many 10's are in the number. // This system of number magnitude works well for route specificity, too. A route written as // `a/b/c` will be more specific than `x/y/z` as long as `a` is more specific than // `x`, irrespective of the other parts. // Because of this similarity, we assign each type of segment a number value written as a // string. We can find the specificity of compound routes by concatenating these strings // together, from left to right. After we have looped through all of the segments, // we convert the string to a number. specificity.val = ''; for (var i=0, l=segments.length; i<l; i++) { var segment = segments[i], match; if (match = segment.match(/^:([^\/]+)$/)) { results.push(new $$route$recognizer$$DynamicSegment(match[1])); names.push(match[1]); specificity.val += '3'; } else if (match = segment.match(/^\*([^\/]+)$/)) { results.push(new $$route$recognizer$$StarSegment(match[1])); specificity.val += '2'; names.push(match[1]); } else if(segment === "") { results.push(new $$route$recognizer$$EpsilonSegment()); specificity.val += '1'; } else { results.push(new $$route$recognizer$$StaticSegment(segment)); specificity.val += '4'; } } specificity.val = +specificity.val; return results; } // A State has a character specification and (`charSpec`) and a list of possible // subsequent states (`nextStates`). // // If a State is an accepting state, it will also have several additional // properties: // // * `regex`: A regular expression that is used to extract parameters from paths // that reached this accepting state. // * `handlers`: Information on how to convert the list of captures into calls // to registered handlers with the specified parameters // * `types`: How many static, dynamic or star segments in this route. Used to // decide which route to use if multiple registered routes match a path. // // Currently, State is implemented naively by looping over `nextStates` and // comparing a character specification against a character. A more efficient // implementation would use a hash of keys pointing at one or more next states. function $$route$recognizer$$State(charSpec) { this.charSpec = charSpec; this.nextStates = []; } $$route$recognizer$$State.prototype = { get: function(charSpec) { var nextStates = this.nextStates; for (var i=0, l=nextStates.length; i<l; i++) { var child = nextStates[i]; var isEqual = child.charSpec.validChars === charSpec.validChars; isEqual = isEqual && child.charSpec.invalidChars === charSpec.invalidChars; if (isEqual) { return child; } } }, put: function(charSpec) { var state; // If the character specification already exists in a child of the current // state, just return that state. if (state = this.get(charSpec)) { return state; } // Make a new state for the character spec state = new $$route$recognizer$$State(charSpec); // Insert the new state as a child of the current state this.nextStates.push(state); // If this character specification repeats, insert the new state as a child // of itself. Note that this will not trigger an infinite loop because each // transition during recognition consumes a character. if (charSpec.repeat) { state.nextStates.push(state); } // Return the new state return state; }, // Find a list of child states matching the next character match: function(ch) { // DEBUG "Processing `" + ch + "`:" var nextStates = this.nextStates, child, charSpec, chars; // DEBUG " " + debugState(this) var returned = []; for (var i=0, l=nextStates.length; i<l; i++) { child = nextStates[i]; charSpec = child.charSpec; if (typeof (chars = charSpec.validChars) !== 'undefined') { if (chars.indexOf(ch) !== -1) { returned.push(child); } } else if (typeof (chars = charSpec.invalidChars) !== 'undefined') { if (chars.indexOf(ch) === -1) { returned.push(child); } } } return returned; } /** IF DEBUG , debug: function() { var charSpec = this.charSpec, debug = "[", chars = charSpec.validChars || charSpec.invalidChars; if (charSpec.invalidChars) { debug += "^"; } debug += chars; debug += "]"; if (charSpec.repeat) { debug += "+"; } return debug; } END IF **/ }; /** IF DEBUG function debug(log) { console.log(log); } function debugState(state) { return state.nextStates.map(function(n) { if (n.nextStates.length === 0) { return "( " + n.debug() + " [accepting] )"; } return "( " + n.debug() + " <then> " + n.nextStates.map(function(s) { return s.debug() }).join(" or ") + " )"; }).join(", ") } END IF **/ // Sort the routes by specificity function $$route$recognizer$$sortSolutions(states) { return states.sort(function(a, b) { return b.specificity.val - a.specificity.val; }); } function $$route$recognizer$$recognizeChar(states, ch) { var nextStates = []; for (var i=0, l=states.length; i<l; i++) { var state = states[i]; nextStates = nextStates.concat(state.match(ch)); } return nextStates; } var $$route$recognizer$$oCreate = Object.create || function(proto) { function F() {} F.prototype = proto; return new F(); }; function $$route$recognizer$$RecognizeResults(queryParams) { this.queryParams = queryParams || {}; } $$route$recognizer$$RecognizeResults.prototype = $$route$recognizer$$oCreate({ splice: Array.prototype.splice, slice: Array.prototype.slice, push: Array.prototype.push, length: 0, queryParams: null }); function $$route$recognizer$$findHandler(state, path, queryParams) { var handlers = state.handlers, regex = state.regex; var captures = path.match(regex), currentCapture = 1; var result = new $$route$recognizer$$RecognizeResults(queryParams); for (var i=0, l=handlers.length; i<l; i++) { var handler = handlers[i], names = handler.names, params = {}; for (var j=0, m=names.length; j<m; j++) { params[names[j]] = captures[currentCapture++]; } result.push({ handler: handler.handler, params: params, isDynamic: !!names.length }); } return result; } function $$route$recognizer$$addSegment(currentState, segment) { segment.eachChar(function(ch) { var state; currentState = currentState.put(ch); }); return currentState; } function $$route$recognizer$$decodeQueryParamPart(part) { // http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4.1 part = part.replace(/\+/gm, '%20'); return decodeURIComponent(part); } // The main interface var $$route$recognizer$$RouteRecognizer = function() { this.rootState = new $$route$recognizer$$State(); this.names = {}; }; $$route$recognizer$$RouteRecognizer.prototype = { add: function(routes, options) { var currentState = this.rootState, regex = "^", specificity = {}, handlers = [], allSegments = [], name; var isEmpty = true; for (var i=0, l=routes.length; i<l; i++) { var route = routes[i], names = []; var segments = $$route$recognizer$$parse(route.path, names, specificity); allSegments = allSegments.concat(segments); for (var j=0, m=segments.length; j<m; j++) { var segment = segments[j]; if (segment instanceof $$route$recognizer$$EpsilonSegment) { continue; } isEmpty = false; // Add a "/" for the new segment currentState = currentState.put({ validChars: "/" }); regex += "/"; // Add a representation of the segment to the NFA and regex currentState = $$route$recognizer$$addSegment(currentState, segment); regex += segment.regex(); } var handler = { handler: route.handler, names: names }; handlers.push(handler); } if (isEmpty) { currentState = currentState.put({ validChars: "/" }); regex += "/"; } currentState.handlers = handlers; currentState.regex = new RegExp(regex + "$"); currentState.specificity = specificity; if (name = options && options.as) { this.names[name] = { segments: allSegments, handlers: handlers }; } }, handlersFor: function(name) { var route = this.names[name], result = []; if (!route) { throw new Error("There is no route named " + name); } for (var i=0, l=route.handlers.length; i<l; i++) { result.push(route.handlers[i]); } return result; }, hasRoute: function(name) { return !!this.names[name]; }, generate: function(name, params) { var route = this.names[name], output = ""; if (!route) { throw new Error("There is no route named " + name); } var segments = route.segments; for (var i=0, l=segments.length; i<l; i++) { var segment = segments[i]; if (segment instanceof $$route$recognizer$$EpsilonSegment) { continue; } output += "/"; output += segment.generate(params); } if (output.charAt(0) !== '/') { output = '/' + output; } if (params && params.queryParams) { output += this.generateQueryString(params.queryParams, route.handlers); } return output; }, generateQueryString: function(params, handlers) { var pairs = []; var keys = []; for(var key in params) { if (params.hasOwnProperty(key)) { keys.push(key); } } keys.sort(); for (var i = 0, len = keys.length; i < len; i++) { key = keys[i]; var value = params[key]; if (value == null) { continue; } var pair = encodeURIComponent(key); if ($$route$recognizer$$isArray(value)) { for (var j = 0, l = value.length; j < l; j++) { var arrayPair = key + '[]' + '=' + encodeURIComponent(value[j]); pairs.push(arrayPair); } } else { pair += "=" + encodeURIComponent(value); pairs.push(pair); } } if (pairs.length === 0) { return ''; } return "?" + pairs.join("&"); }, parseQueryString: function(queryString) { var pairs = queryString.split("&"), queryParams = {}; for(var i=0; i < pairs.length; i++) { var pair = pairs[i].split('='), key = $$route$recognizer$$decodeQueryParamPart(pair[0]), keyLength = key.length, isArray = false, value; if (pair.length === 1) { value = 'true'; } else { //Handle arrays if (keyLength > 2 && key.slice(keyLength -2) === '[]') { isArray = true; key = key.slice(0, keyLength - 2); if(!queryParams[key]) { queryParams[key] = []; } } value = pair[1] ? $$route$recognizer$$decodeQueryParamPart(pair[1]) : ''; } if (isArray) { queryParams[key].push(value); } else { queryParams[key] = value; } } return queryParams; }, recognize: function(path) { var states = [ this.rootState ], pathLen, i, l, queryStart, queryParams = {}, isSlashDropped = false; queryStart = path.indexOf('?'); if (queryStart !== -1) { var queryString = path.substr(queryStart + 1, path.length); path = path.substr(0, queryStart); queryParams = this.parseQueryString(queryString); } path = decodeURI(path); // DEBUG GROUP path if (path.charAt(0) !== "/") { path = "/" + path; } pathLen = path.length; if (pathLen > 1 && path.charAt(pathLen - 1) === "/") { path = path.substr(0, pathLen - 1); isSlashDropped = true; } for (i=0, l=path.length; i<l; i++) { states = $$route$recognizer$$recognizeChar(states, path.charAt(i)); if (!states.length) { break; } } // END DEBUG GROUP var solutions = []; for (i=0, l=states.length; i<l; i++) { if (states[i].handlers) { solutions.push(states[i]); } } states = $$route$recognizer$$sortSolutions(solutions); var state = solutions[0]; if (state && state.handlers) { // if a trailing slash was dropped and a star segment is the last segment // specified, put the trailing slash back if (isSlashDropped && state.regex.source.slice(-5) === "(.+)$") { path = path + "/"; } return $$route$recognizer$$findHandler(state, path, queryParams); } } }; $$route$recognizer$$RouteRecognizer.prototype.map = $$route$recognizer$dsl$$default; $$route$recognizer$$RouteRecognizer.VERSION = '0.1.9'; var $$route$recognizer$$default = $$route$recognizer$$RouteRecognizer; /* global define:true module:true window: true */ if ("function" === 'function' && __webpack_require__(6)['amd']) { !(__WEBPACK_AMD_DEFINE_RESULT__ = function() { return $$route$recognizer$$default; }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); } else if (typeof module !== 'undefined' && module['exports']) { module['exports'] = $$route$recognizer$$default; } else if (typeof this !== 'undefined') { this['RouteRecognizer'] = $$route$recognizer$$default; } }).call(this); //# sourceMappingURL=route-recognizer.js.map /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(5)(module))) /***/ }, /* 5 */ /***/ function(module, exports) { module.exports = function(module) { if(!module.webpackPolyfill) { module.deprecate = function() {}; module.paths = []; // module.parent = undefined by default module.children = []; module.webpackPolyfill = 1; } return module; } /***/ }, /* 6 */ /***/ function(module, exports) { module.exports = function() { throw new Error("define cannot be used indirect"); }; /***/ }, /* 7 */ /***/ function(module, exports, __webpack_require__) { 'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var _util = __webpack_require__(3); exports['default'] = function (Vue, Router) { /** * Register a map of top-level paths. * * @param {Object} map */ Router.prototype.map = function (map) { for (var route in map) { this.on(route, map[route]); } }; /** * Register a single root-level path * * @param {String} rootPath * @param {Object} handler * - {String} component * - {Object} [subRoutes] * - {Boolean} [forceRefresh] * - {Function} [before] * - {Function} [after] */ Router.prototype.on = function (rootPath, handler) { if (rootPath === '*') { this._notFound(handler); } else { this._addRoute(rootPath, handler, []); } }; /** * Set redirects. * * @param {Object} map */ Router.prototype.redirect = function (map) { for (var path in map) { this._addRedirect(path, map[path]); } }; /** * Set aliases. * * @param {Object} map */ Router.prototype.alias = function (map) { for (var path in map) { this._addAlias(path, map[path]); } }; /** * Set global before hook. * * @param {Function} fn */ Router.prototype.beforeEach = function (fn) { this._beforeEachHooks.push(fn); }; /** * Set global after hook. * * @param {Function} fn */ Router.prototype.afterEach = function (fn) { this._afterEachHooks.push(fn); }; /** * Navigate to a given path. * The path can be an object describing a named path in * the format of { name: '...', params: {}, query: {}} * The path is assumed to be already decoded, and will * be resolved against root (if provided) * * @param {String|Object} path * @param {Boolean} [replace] */ Router.prototype.go = function (path, replace) { path = this._normalizePath(path); this.history.go(path, replace); }; /** * Short hand for replacing current path * * @param {String} path */ Router.prototype.replace = function (path) { this.go(path, true); }; /** * Start the router. * * @param {VueConstructor} App * @param {String|Element} container */ Router.prototype.start = function (App, container) { /* istanbul ignore if */ if (this._started) { (0, _util.warn)('already started.'); return; } this._started = true; if (!this.app) { /* istanbul ignore if */ if (!App || !container) { throw new Error('Must start vue-router with a component and a ' + 'root container.'); } this._appContainer = container; this._appConstructor = typeof App === 'function' ? App : Vue.extend(App); } this.history.start(); }; /** * Stop listening to route changes. */ Router.prototype.stop = function () { this.history.stop(); this._started = false; }; }; module.exports = exports['default']; /***/ }, /* 8 */ /***/ function(module, exports, __webpack_require__) { 'use strict'; var _interopRequireDefault = __webpack_require__(2)['default']; Object.defineProperty(exports, '__esModule', { value: true }); var _util = __webpack_require__(3); var _route = __webpack_require__(9); var _route2 = _interopRequireDefault(_route); var _transition = __webpack_require__(10); var _transition2 = _interopRequireDefault(_transition); exports['default'] = function (Vue, Router) { var _ = Vue.util; /** * Add a route containing a list of segments to the internal * route recognizer. Will be called recursively to add all * possible sub-routes. * * @param {String} path * @param {Object} handler * @param {Array} segments */ Router.prototype._addRoute = function (path, handler, segments) { guardComponent(handler); segments.push({ path: path, handler: handler }); this._recognizer.add(segments, { as: handler.name }); // add sub routes if (handler.subRoutes) { for (var subPath in handler.subRoutes) { // recursively walk all sub routes this._addRoute(subPath, handler.subRoutes[subPath], // pass a copy in recursion to avoid mutating // across branches segments.slice()); } } }; /** * Set the notFound route handler. * * @param {Object} handler */ Router.prototype._notFound = function (handler) { guardComponent(handler); this._notFoundHandler = [{ handler: handler }]; }; /** * Add a redirect record. * * @param {String} path * @param {String} redirectPath */ Router.prototype._addRedirect = function (path, redirectPath) { this._addGuard(path, redirectPath, this.replace); }; /** * Add an alias record. * * @param {String} path * @param {String} aliasPath */ Router.prototype._addAlias = function (path, aliasPath) { this._addGuard(path, aliasPath, this._match); }; /** * Add a path guard. * * @param {String} path * @param {String} mappedPath * @param {Function} handler */ Router.prototype._addGuard = function (path, mappedPath, _handler) { var _this = this; this._guardRecognizer.add([{ path: path, handler: function handler(match, query) { var realPath = (0, _util.mapParams)(mappedPath, match.params, query); _handler.call(_this, realPath); } }]); }; /** * Check if a path matches any redirect records. * * @param {String} path * @return {Boolean} - if true, will skip normal match. */ Router.prototype._checkGuard = function (path) { var matched = this._guardRecognizer.recognize(path); if (matched) { matched[0].handler(matched[0], matched.queryParams); return true; } }; /** * Match a URL path and set the route context on vm, * triggering view updates. * * @param {String} path * @param {Object} [state] * @param {String} [anchor] */ Router.prototype._match = function (path, state, anchor) { var _this2 = this; if (this._checkGuard(path)) { return; } var prevRoute = this._currentRoute; var prevTransition = this._currentTransition; // do nothing if going to the same route. // the route only changes when a transition successfully // reaches activation; we don't need to do anything // if an ongoing transition is aborted during validation // phase. if (prevTransition && path === prevRoute.path) { return; } // construct new route and transition context var route = new _route2['default'](path, this); var transition = new _transition2['default'](this, route, prevRoute); this._prevTransition = prevTransition; this._currentTransition = transition; if (!this.app) { // initial render this.app = new this._appConstructor({ el: this._appContainer, _meta: { $route: route } }); } // check global before hook var beforeHooks = this._beforeEachHooks; var startTransition = function startTransition() { transition.start(function () { _this2._postTransition(route, state, anchor); }); }; if (beforeHooks.length) { transition.runQueue(beforeHooks, function (hook, _, next) { if (transition === _this2._currentTransition) { transition.callHook(hook, null, next, true); } }, startTransition); } else { startTransition(); } // HACK: // set rendered to true after the transition start, so // that components that are acitvated synchronously know // whether it is the initial render. this._rendered = true; }; /** * Set current to the new transition. * This is called by the transition object when the * validation of a route has succeeded. * * @param {RouteTransition} transition */ Router.prototype._onTransitionValidated = function (transition) { // now that this one is validated, we can abort // the previous transition. var prevTransition = this._prevTransition; if (prevTransition) { prevTransition.aborted = true; } // set current route var route = this._currentRoute = transition.to; // update route context for all children if (this.app.$route !== route) { this.app.$route = route; this._children.forEach(function (child) { child.$route = route; }); } // call global after hook if (this._afterEachHooks.length) { this._afterEachHooks.forEach(function (hook) { return hook.call(null, { to: transition.to, from: transition.from }); }); } this._currentTransition.done = true; }; /** * Handle stuff after the transition. * * @param {Route} route * @param {Object} [state] * @param {String} [anchor] */ Router.prototype._postTransition = function (route, state, anchor) { // handle scroll positions // saved scroll positions take priority // then we check if the path has an anchor var pos = state && state.pos; if (pos && this._saveScrollPosition) { Vue.nextTick(function () { window.scrollTo(pos.x, pos.y); }); } else if (anchor) { Vue.nextTick(function () { var el = document.getElementById(anchor.slice(1)); if (el) { window.scrollTo(window.scrollX, el.offsetTop); } }); } }; /** * Normalize named route object / string paths into * a string. * * @param {Object|String|Number} path * @return {String} */ Router.prototype._normalizePath = function (path) { if (typeof path === 'object') { if (path.name) { var params = path.params || {}; if (path.query) { params.queryParams = path.query; } return this._recognizer.generate(path.name, params); } else if (path.path) { return path.path; } else { return ''; } } else { return path + ''; } }; /** * Allow directly passing components to a route * definition. * * @param {Object} handler */ function guardComponent(handler) { var comp = handler.component; if (_.isPlainObject(comp)) { comp = handler.component = Vue.extend(comp); } /* istanbul ignore if */ if (typeof comp !== 'function') { handler.component = null; (0, _util.warn)('invalid component for route "' + handler.path + '"'); } } }; module.exports = exports['default']; /***/ }, /* 9 */ /***/ function(module, exports, __webpack_require__) { "use strict"; var _classCallCheck = __webpack_require__(1)["default"]; Object.defineProperty(exports, "__esModule", { value: true }); var internalKeysRE = /^(component|subRoutes|name)$/; /** * Route Context Object * * @param {String} path * @param {Router} router */ var Route = function Route(path, router) { var _this = this; _classCallCheck(this, Route); var matched = router._recognizer.recognize(path); if (matched) { // copy all custom fields from route configs [].forEach.call(matched, function (match) { for (var key in match.handler) { if (!internalKeysRE.test(key)) { _this[key] = match.handler[key]; } } }); // set query and params this.query = matched.queryParams; this.params = [].reduce.call(matched, function (prev, cur) { if (cur.params) { for (var key in cur.params) { prev[key] = cur.params[key]; } } return prev; }, {}); } // expose path and router this.path = path; this.router = router; // for internal use this._matched = matched || router._notFoundHandler; }; exports["default"] = Route; module.exports = exports["default"]; /***/ }, /* 10 */ /***/ function(module, exports, __webpack_require__) { 'use strict'; var _createClass = __webpack_require__(11)['default']; var _classCallCheck = __webpack_require__(1)['default']; Object.defineProperty(exports, '__esModule', { value: true }); var _util = __webpack_require__(3); var _pipeline = __webpack_require__(15); /** * A RouteTransition object manages the pipeline of a * router-view switching process. This is also the object * passed into user route hooks. * * @param {Router} router * @param {Route} to * @param {Route} from */ var RouteTransition = (function () { function RouteTransition(router, to, from) { _classCallCheck(this, RouteTransition); this.router = router; this.to = to; this.from = from; this.next = null; this.aborted = false; this.done = false; // start by determine the queues // the deactivate queue is an array of router-view // directive instances that need to be deactivated, // deepest first. this.deactivateQueue = router._views; // check the default handler of the deepest match var matched = to._matched ? Array.prototype.slice.call(to._matched) : []; // the activate queue is an array of route handlers // that need to be activated this.activateQueue = matched.map(function (match) { return match.handler; }); } /** * Abort current transition and return to previous location. */ _createClass(RouteTransition, [{ key: 'abort', value: function abort() { if (!this.aborted) { this.aborted = true; // if the root path throws an error during validation // on initial load, it gets caught in an infinite loop. var abortingOnLoad = !this.from.path && this.to.path === '/'; if (!abortingOnLoad) { this.router.replace(this.from.path || '/'); } } } /** * Abort current transition and redirect to a new location. * * @param {String} path */ }, { key: 'redirect', value: function redirect(path) { if (!this.aborted) { this.aborted = true; if (typeof path === 'string') { path = (0, _util.mapParams)(path, this.to.params, this.to.query); } else { path.params = this.to.params; path.query = this.to.query; } this.router.replace(path); } } /** * A router view transition's pipeline can be described as * follows, assuming we are transitioning from an existing * <router-view> chain [Component A, Component B] to a new * chain [Component A, Component C]: * * A A * | => | * B C * * 1. Reusablity phase: * -> canReuse(A, A) * -> canReuse(B, C) * -> determine new queues: * - deactivation: [B] * - activation: [C] * * 2. Validation phase: * -> canDeactivate(B) * -> canActivate(C) * * 3. Activation phase: * -> deactivate(B) * -> activate(C) * * Each of these steps can be asynchronous, and any * step can potentially abort the transition. * * @param {Functio