/*! * vue-router v0.7.5 * (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']; exports.__esModule = true; var _util = __webpack_require__(3); var _util2 = _interopRequireDefault(_util); var _override = __webpack_require__(7); var _override2 = _interopRequireDefault(_override); var _routeRecognizer = __webpack_require__(4); var _routeRecognizer2 = _interopRequireDefault(_routeRecognizer); var _route = __webpack_require__(8); var _route2 = _interopRequireDefault(_route); var _transition = __webpack_require__(18); var _transition2 = _interopRequireDefault(_transition); var _directivesView = __webpack_require__(28); var _directivesView2 = _interopRequireDefault(_directivesView); var _directivesLink = __webpack_require__(29); var _directivesLink2 = _interopRequireDefault(_directivesLink); var _historyAbstract = __webpack_require__(30); var _historyAbstract2 = _interopRequireDefault(_historyAbstract); var _historyHash = __webpack_require__(31); var _historyHash2 = _interopRequireDefault(_historyHash); var _historyHtml5 = __webpack_require__(32); var _historyHtml52 = _interopRequireDefault(_historyHtml5); var historyBackends = { abstract: _historyAbstract2['default'], hash: _historyHash2['default'], html5: _historyHtml52['default'] }; // late bind during install var Vue = undefined; /** * Router constructor * * @param {Object} [options] */ var Router = (function () { 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._startCb = null; this._currentRoute = {}; this._currentTransition = null; this._previousTransition = null; this._notFoundHandler = null; this._notFoundRedirect = 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 = 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); } }); } /** * Allow directly passing components to a route * definition. * * @param {String} path * @param {Object} handler */ // API =================================================== /** * Register a map of top-level paths. * * @param {Object} map */ Router.prototype.map = function map(_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 on(rootPath, handler) { if (rootPath === '*') { this._notFound(handler); } else { this._addRoute(rootPath, handler, []); } }; /** * Set redirects. * * @param {Object} map */ Router.prototype.redirect = function redirect(map) { for (var path in map) { this._addRedirect(path, map[path]); } }; /** * Set aliases. * * @param {Object} map */ Router.prototype.alias = function alias(map) { for (var path in map) { this._addAlias(path, map[path]); } }; /** * Set global before hook. * * @param {Function} fn */ Router.prototype.beforeEach = function beforeEach(fn) { this._beforeEachHooks.push(fn); }; /** * Set global after hook. * * @param {Function} fn */ Router.prototype.afterEach = function afterEach(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 go(path) { var replace = false; var append = false; if (Vue.util.isObject(path)) { replace = path.replace; append = path.append; } path = this._stringifyPath(path); if (path) { this.history.go(path, replace, append); } }; /** * Short hand for replacing current path * * @param {String} path */ Router.prototype.replace = function replace(path) { this.go({ path: path, replace: true }); }; /** * Start the router. * * @param {VueConstructor} App * @param {String|Element} container * @param {Function} [cb] */ Router.prototype.start = function start(App, container, cb) { /* istanbul ignore if */ if (this._started) { _util.warn('already started.'); return; } this._started = true; this._startCb = cb; 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; var Ctor = this._appConstructor = typeof App === 'function' ? App : Vue.extend(App); // give it a name for better debugging Ctor.options.name = Ctor.options.name || 'RouterApp'; } this.history.start(); }; /** * Stop listening to route changes. */ Router.prototype.stop = function stop() { this.history.stop(); this._started = false; }; // Internal methods ====================================== /** * 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 _addRoute(path, handler, segments) { guardComponent(path, handler); handler.path = path; handler.fullPath = (segments.reduce(function (path, segment) { return path + segment.path; }, '') + path).replace('//', '/'); 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 _notFound(handler) { guardComponent('*', handler); this._notFoundHandler = [{ handler: handler }]; }; /** * Add a redirect record. * * @param {String} path * @param {String} redirectPath */ Router.prototype._addRedirect = function _addRedirect(path, redirectPath) { if (path === '*') { this._notFoundRedirect = redirectPath; } else { this._addGuard(path, redirectPath, this.replace); } }; /** * Add an alias record. * * @param {String} path * @param {String} aliasPath */ Router.prototype._addAlias = function _addAlias(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 _addGuard(path, mappedPath, _handler) { var _this = this; this._guardRecognizer.add([{ path: path, handler: function handler(match, query) { var realPath = _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 _checkGuard(path) { var matched = this._guardRecognizer.recognize(path); if (matched) { matched[0].handler(matched[0], matched.queryParams); return true; } else if (this._notFoundRedirect) { matched = this._recognizer.recognize(path); if (!matched) { this.replace(this._notFoundRedirect); 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 _match(path, state, anchor) { var _this2 = this; if (this._checkGuard(path)) { return; } var currentRoute = this._currentRoute; var currentTransition = this._currentTransition; if (currentTransition) { if (currentTransition.to.path === path) { // do nothing if we have an active transition going to the same path return; } else if (currentRoute.path === path) { // We are going to the same path, but we also have an ongoing but // not-yet-validated transition. Abort that transition and reset to // prev transition. currentTransition.aborted = true; this._currentTransition = this._prevTransition; return; } else { // going to a totally different path. abort ongoing transition. currentTransition.aborted = true; } } // construct new route and transition context var route = new _route2['default'](path, this); var transition = new _transition2['default'](this, route, currentRoute); // current transition is updated right now. // however, current route will only be updated after the transition has // been validated. this._prevTransition = currentTransition; 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, { expectBoolean: true }); } }, startTransition); } else { startTransition(); } if (!this._rendered && this._startCb) { this._startCb.call(null); } // 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 {Transition} transition */ Router.prototype._onTransitionValidated = function _onTransitionValidated(transition) { // 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 _postTransition(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._stringifyPath = function _stringifyPath(path) { if (path && 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 ? path + '' : ''; } }; return Router; })(); function guardComponent(path, handler) { var comp = handler.component; if (Vue.util.isPlainObject(comp)) { comp = handler.component = Vue.extend(comp); } /* istanbul ignore if */ if (typeof comp !== 'function') { handler.component = null; _util.warn('invalid component for route "' + path + '".'); } } /* Installation */ Router.installed = false; /** * Installation interface. * Install the necessary directives. */ Router.install = function (externalVue) { /* istanbul ignore if */ if (Router.installed) { _util.warn('already installed.'); return; } Vue = externalVue; _override2['default'](Vue); _directivesView2['default'](Vue); _directivesLink2['default'](Vue); _util2['default'].Vue = Vue; Router.installed = true; }; // auto install /* istanbul ignore if */ if (typeof window !== 'undefined' && window.Vue) { window.Vue.use(Router); } exports['default'] = 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']; exports.__esModule = 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 */ function warn(msg) { /* istanbul ignore next */ if (window.console) { console.warn('[vue-router] ' + msg); /* istanbul ignore if */ if (!_exports.Vue || _exports.Vue.config.debug) { console.warn(new Error('warning stack trace:').stack); } } } /** * Resolve a relative path. * * @param {String} base * @param {String} relative * @param {Boolean} append * @return {String} */ function resolvePath(base, relative, append) { 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 if: // - not appending // - appending to trailing slash (last segment is empty) if (!append || !stack[stack.length - 1]) { stack.pop(); } // resolve relative path var segments = relative.replace(/^\//, '').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) { if (params === undefined) params = {}; path = path.replace(/:([^\/]+)/g, function (_, key) { var val = params[key]; if (!val) { warn('param "' + key + '" not found when generating ' + 'path for "' + path + '" with params ' + JSON.stringify(params)); } return val || ''; }); if (query) { path += genQuery(query); } return path; } /***/ }, /* 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) { 'use strict'; exports.__esModule = true; exports['default'] = function (Vue) { var _ = Vue.util; // override Vue's init and destroy process to keep track of router instances var init = Vue.prototype._init; Vue.prototype._init = function (options) { var root = options._parent || options.parent || this; var route = root.$route; if (route) { route.router._children.push(this); if (!this.$route) { /* istanbul ignore if */ if (this._defineMeta) { // 0.12 this._defineMeta('$route', route); } else { // 1.0 _.defineReactive(this, '$route', route); } } } init.call(this, options); }; var destroy = Vue.prototype._destroy; Vue.prototype._destroy = function () { if (!this._isBeingDestroyed) { var route = this.$root.$route; if (route) { route.router._children.$remove(this); } destroy.apply(this, arguments); } }; // 1.0 only: enable route mixins var strats = Vue.config.optionMergeStrategies; var hooksToMergeRE = /^(data|activate|deactivate)$/; if (strats) { strats.route = function (parentVal, childVal) { if (!childVal) return parentVal; if (!parentVal) return childVal; var ret = {}; _.extend(ret, parentVal); for (var key in childVal) { var a = ret[key]; var b = childVal[key]; // for data, activate and deactivate, we need to merge them into // arrays similar to lifecycle hooks. if (a && hooksToMergeRE.test(key)) { ret[key] = (_.isArray(a) ? a : [a]).concat(b); } else { ret[key] = b; } } return ret; }; } }; module.exports = exports['default']; /***/ }, /* 8 */ /***/ function(module, exports, __webpack_require__) { "use strict"; var _classCallCheck = __webpack_require__(1)["default"]; var _Object$freeze = __webpack_require__(9)["default"]; exports.__esModule = true; var internalKeysRE = /^(component|subRoutes)$/; /** * 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; // Important: freeze self to prevent observation _Object$freeze(this); }; exports["default"] = Route; module.exports = exports["default"]; /***/ }, /* 9 */ /***/ function(module, exports, __webpack_require__) { module.exports = { "default": __webpack_require__(10), __esModule: true }; /***/ }, /* 10 */ /***/ function(module, exports, __webpack_require__) { __webpack_require__(11); module.exports = __webpack_require__(16).Object.freeze; /***/ }, /* 11 */ /***/ function(module, exports, __webpack_require__) { // 19.1.2.5 Object.freeze(O) var isObject = __webpack_require__(12); __webpack_require__(13)('freeze', function($freeze){ return function freeze(it){ return $freeze && isObject(it) ? $freeze(it) : it; }; }); /***/ }, /* 12 */ /***/ function(module, exports) { // http://jsperf.com/core-js-isobject module.exports = function(it){ return it !== null && (typeof it == 'object' || typeof it == 'function'); }; /***/ }, /* 13 */ /***/ function(module, exports, __webpack_require__) { // most Object methods by ES6 should accept primitives module.exports = function(KEY, exec){ var $def = __webpack_require__(14) , fn = (__webpack_require__(16).Object || {})[KEY] || Object[KEY] , exp = {}; exp[KEY] = exec(fn); $def($def.S + $def.F * __webpack_require__(17)(function(){ fn(1); }), 'Object', exp); }; /***/ }, /* 14 */ /***/ function(module, exports, __webpack_require__) { var global = __webpack_require__(15) , core = __webpack_require__(16) , PROTOTYPE = 'prototype'; var ctx = function(fn, that){ return function(){ return fn.apply(that, arguments); }; }; var $def = function(type, name, source){ var key, own, out, exp , isGlobal = type & $def.G , isProto = type & $def.P , target = isGlobal ? global : type & $def.S ? global[name] : (global[name] || {})[PROTOTYPE] , exports = isGlobal ? core : core[name] || (core[name] = {}); if(isGlobal)source = name; for(key in source){ // contains in native own = !(type & $def.F) && target && key in target; if(own && key in exports)continue; // export native or passed out = own ? target[key] : source[key]; // prevent global pollution for namespaces if(isGlobal && typeof target[key] != 'function')exp = source[key]; // bind timers to global for call from export context else if(type & $def.B && own)exp = ctx(out, global); // wrap global constructors for prevent change them in library else if(type & $def.W && target[key] == out)!function(C){ exp = function(param){ return this instanceof C ? new C(param) : C(param); }; exp[PROTOTYPE] = C[PROTOTYPE]; }(out); else exp = isProto && typeof out == 'function' ? ctx(Function.call, out) : out; // export exports[key] = exp; if(isProto)(exports[PROTOTYPE] || (exports[PROTOTYPE] = {}))[key] = out; } }; // type bitmap $def.F = 1; // forced $def.G = 2; // global $def.S = 4; // static $def.P = 8; // proto $def.B = 16; // bind $def.W = 32; // wrap module.exports = $def; /***/ }, /* 15 */ /***/ function(module, exports) { // https://github.com/zloirock/core-js/issues/86#issuecomment-115759028 var UNDEFINED = 'undefined'; var global = module.exports = typeof window != UNDEFINED && window.Math == Math ? window : typeof self != UNDEFINED && self.Math == Math ? self : Function('return this')(); if(typeof __g == 'number')__g = global; // eslint-disable-line no-undef /***/ }, /* 16 */ /***/ function(module, exports) { var core = module.exports = {}; if(typeof __e == 'number')__e = core; // eslint-disable-line no-undef /***/ }, /* 17 */ /***/ function(module, exports) { module.exports = function(exec){ try { return !!exec(); } catch(e){ return true; } }; /***/ }, /* 18 */ /***/ function(module, exports, __webpack_require__) { 'use strict'; var _classCallCheck = __webpack_require__(1)['default']; exports.__esModule = true; var _util = __webpack_require__(3); var _pipeline = __webpack_require__(19); /** * 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. */ RouteTransition.prototype.abort = 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 */ RouteTransition.prototype.redirect = function redirect(path) { if (!this.aborted) { this.aborted = true; if (typeof path === 'string') { path = _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 {Function} cb */ RouteTransition.prototype.start = function start(cb) { var transition = this; var daq = this.deactivateQueue; var aq = this.activateQueue; var rdaq = daq.slice().reverse(); var reuseQueue = undefined; // 1. Reusability phase var i = undefined; for (i = 0; i < rdaq.length; i++) { if (!_pipeline.canReuse(rdaq[i], aq[i], transition)) { break; } } if (i > 0) { reuseQueue = rdaq.slice(0, i); daq = rdaq.slice(i).reverse(); aq = aq.slice(i); } // 2. Validation phase transition.runQueue(daq, _pipeline.canDeactivate, function () { transition.runQueue(aq, _pipeline.canActivate, function () { transition.runQueue(daq, _pipeline.deactivate, function () { // 3. Activation phase // Update router current route transition.router._onTransitionValidated(transition); // trigger reuse for all reused views reuseQueue && reuseQueue.forEach(function (view) { _pipeline.reuse(view, transition); }); // the root of the chain that needs to be replaced // is the top-most non-reusable view. if (daq.length) { var view = daq[daq.length - 1]; var depth = reuseQueue ? reuseQueue.length : 0; _pipeline.activate(view, transition, depth, cb); } else { cb(); } }); }); }); }; /** * Asynchronously and sequentially apply a function to a * queue. * * @param {Array} queue * @param {Function} fn * @param {Function} cb */ RouteTransition.prototype.runQueue = function runQueue(queue, fn, cb) { var transition = this; step(0); function step(index) { if (index >= queue.length) { cb(); } else { fn(queue[index], transition, function () { step(index + 1); }); } } }; /** * Call a user provided route transition hook and handle * the response (e.g. if the user returns a promise). * * If the user neither expects an argument nor returns a * promise, the hook is assumed to be synchronous. * * @param {Function} hook * @param {*} [context] * @param {Function} [cb] * @param {Object} [options] * - {Boolean} expectBoolean * - {Boolean} expectData * - {Function} cleanup */ RouteTransition.prototype.callHook = function callHook(hook, context, cb) { var _ref = arguments.length <= 3 || arguments[3] === undefined ? {} : arguments[3]; var _ref$expectBoolean = _ref.expectBoolean; var expectBoolean = _ref$expectBoolean === undefined ? false : _ref$expectBoolean; var _ref$expectData = _ref.expectData; var expectData = _ref$expectData === undefined ? false : _ref$expectData; var cleanup = _ref.cleanup; var transition = this; var nextCalled = false; // abort the transition var abort = function abort() { cleanup && cleanup(); transition.abort(); }; // handle errors var onError = function onError(err) { // cleanup indicates an after-activation hook, // so instead of aborting we just let the transition // finish. cleanup ? next() : abort(); if (err && !transition.router._suppress) { _util.warn('Uncaught error during transition: '); throw err instanceof Error ? err : new Error(err); } }; // advance the transition to the next step var next = function next(data) { if (nextCalled) { _util.warn('transition.next() should be called only once.'); return; } nextCalled = true; if (transition.aborted) { cleanup && cleanup(); return; } cb && cb(data, onError); }; // expose a clone of the transition object, so that each // hook gets a clean copy and prevent the user from // messing with the internals. var exposed = { to: transition.to, from: transition.from, abort: abort, next: next, redirect: function redirect() { transition.redirect.apply(transition, arguments); } }; // actually call the hook var res = undefined; try { res = hook.call(context, exposed); } catch (err) { return onError(err); } // handle boolean/promise return values var resIsPromise = _util.isPromise(res); if (expectBoolean) { if (typeof res === 'boolean') { res ? next() : abort(); } else if (resIsPromise) { res.then(function (ok) { ok ? next() : abort(); }, onError); } else if (!hook.length) { next(res); } } else if (resIsPromise) { res.then(next, onError); } else if (expectData && isPlainOjbect(res) || !hook.length) { next(res); } }; /** * Call a single hook or an array of async hooks in series. * * @param {Array} hooks * @param {*} context * @param {Function} cb * @param {Object} [options] */ RouteTransition.prototype.callHooks = function callHooks(hooks, context, cb, options) { var _this = this; if (Array.isArray(hooks)) { (function () { var res = []; res._needMerge = true; var onError = undefined; _this.runQueue(hooks, function (hook, _, next) { if (!_this.aborted) { _this.callHook(hook, context, function (r, onError) { if (r) res.push(r); onError = onError; next(); }, options); } }, function () { cb(res, onError); }); })(); } else { this.callHook(hooks, context, cb, options); } }; return RouteTransition; })(); exports['default'] = RouteTransition; function isPlainOjbect(val) { return Object.prototype.toString.call(val) === '[object Object]'; } module.exports = exports['default']; /***/ }, /* 19 */ /***/ function(module, exports, __webpack_require__) { 'use strict'; var _Object$keys = __webpack_require__(20)['default']; var _Object$create = __webpack_require__(25)['default']; exports.__esModule = true; exports.canReuse = canReuse; exports.canDeactivate = canDeactivate; exports.canActivate = canActivate; exports.deactivate = deactivate; exports.activate = activate; exports.reuse = reuse; var _util = __webpack_require__(3); /** * Determine the reusability of an existing router view. * * @param {Directive} view * @param {Object} handler * @param {Transition} transition */ function canReuse(view, handler, transition) { var component = view.childVM; if (!component || !handler) { return false; } // important: check view.Component here because it may // have been changed in activate hook if (view.Component !== handler.component) { return false; } var canReuseFn = _util.getRouteConfig(component, 'canReuse'); return typeof canReuseFn === 'boolean' ? canReuseFn : canReuseFn ? canReuseFn.call(component, { to: transition.to, from: transition.from }) : true; // defaults to true } /** * Check if a component can deactivate. * * @param {Directive} view * @param {Transition} transition * @param {Function} next */ function canDeactivate(view, transition, next) { var fromComponent = view.childVM; var hook = _util.getRouteConfig(fromComponent, 'canDeactivate'); if (!hook) { next(); } else { transition.callHook(hook, fromComponent, next, { expectBoolean: true }); } } /** * Check if a component can activate. * * @param {Object} handler * @param {Transition} transition * @param {Function} next */ function canActivate(handler, transition, next) { _util.resolveAsyncComponent(handler, function (Component) { // have to check due to async-ness if (transition.aborted) { return; } // determine if this component can be activated var hook = _util.getRouteConfig(Component, 'canActivate'); if (!hook) { next(); } else { transition.callHook(hook, null, next, { expectBoolean: true }); } }); } /** * Call deactivate hooks for existing router-views. * * @param {Directive} view * @param {Transition} transition * @param {Function} next */ function deactivate(view, transition, next) { var component = view.childVM; var hook = _util.getRouteConfig(component, 'deactivate'); if (!hook) { next(); } else { transition.callHooks(hook, component, next); } } /** * Activate / switch component for a router-view. * * @param {Directive} view * @param {Transition} transition * @param {Number} depth * @param {Function} [cb] */ function activate(view, transition, depth, cb, reuse) { var handler = transition.activateQueue[depth]; if (!handler) { // fix 1.0.0-alpha.3 compat if (view._bound) { view.setComponent(null); } cb && cb(); return; } var Component = view.Component = handler.component; var activateHook = _util.getRouteConfig(Component, 'activate'); var dataHook = _util.getRouteConfig(Component, 'data'); var waitForData = _util.getRouteConfig(Component, 'waitForData'); view.depth = depth; view.activated = false; var component = undefined; var loading = !!(dataHook && !waitForData); // "reuse" is a flag passed down when the parent view is // either reused via keep-alive or as a child of a kept-alive view. // of course we can only reuse if the current kept-alive instance // is of the correct type. reuse = reuse && view.childVM && view.childVM.constructor === Component; if (reuse) { // just reuse component = view.childVM; component.$loadingRouteData = loading; } else { // unbuild current component. this step also destroys // and removes all nested child views. view.unbuild(true); // handle keep-alive. // if the view has keep-alive, the child vm is not actually // destroyed - its nested views will still be in router's // view list. We need to removed these child views and // cache them on the child vm. if (view.keepAlive) { var views = transition.router._views; var i = views.indexOf(view); if (i > 0) { transition.router._views = views.slice(i); if (view.childVM) { view.childVM._routerViews = views.slice(0, i); } } } // build the new component. this will also create the // direct child view of the current one. it will register // itself as view.childView. component = view.build({ _meta: { $loadingRouteData: loading } }); // handle keep-alive. // when a kept-alive child vm is restored, we need to // add its cached child views into the router's view list, // and also properly update current view's child view. if (view.keepAlive) { component.$loadingRouteData = loading; var cachedViews = component._routerViews; if (cachedViews) { transition.router._views = cachedViews.concat(transition.router._views); view.childView = cachedViews[cachedViews.length - 1]; component._routerViews = null; } } } // cleanup the component in case the transition is aborted // before the component is ever inserted. var cleanup = function cleanup() { component.$destroy(); }; // actually insert the component and trigger transition var insert = function insert() { if (reuse) { cb && cb(); return; } var router = transition.router; if (router._rendered || router._transitionOnLoad) { view.transition(component); } else { // no transition on first render, manual transition /* istanbul ignore if */ if (view.setCurrent) { // 0.12 compat view.setCurrent(component); } else { // 1.0 view.childVM = component; } component.$before(view.anchor, null, false); } cb && cb(); }; // called after activation hook is resolved var afterActivate = function afterActivate() { view.activated = true; // activate the child view if (view.childView) { activate(view.childView, transition, depth + 1, null, reuse || view.keepAlive); } if (dataHook && waitForData) { // wait until data loaded to insert loadData(component, transition, dataHook, insert, cleanup); } else { // load data and insert at the same time if (dataHook) { loadData(component, transition, dataHook); } insert(); } }; if (activateHook) { transition.callHooks(activateHook, component, afterActivate, { cleanup: cleanup }); } else { afterActivate(); } } /** * Reuse a view, just reload data if necessary. * * @param {Directive} view * @param {Transition} transition */ function reuse(view, transition) { var component = view.childVM; var dataHook = _util.getRouteConfig(component, 'data'); if (dataHook) { loadData(component, transition, dataHook); } } /** * Asynchronously load and apply data to component. * * @param {Vue} component * @param {Transition} transition * @param {Function} hook * @param {Function} cb * @param {Function} cleanup */ function loadData(component, transition, hook, cb, cleanup) { component.$loadingRouteData = true; transition.callHooks(hook, component, function (data, onError) { // merge data from multiple data hooks if (Array.isArray(data) && data._needMerge) { data = data.reduce(function (res, obj) { if (isPlainObject(obj)) { _Object$keys(obj).forEach(function (key) { res[key] = obj[key]; }); } return res; }, _Object$create(null)); } // handle promise sugar syntax var promises = []; if (isPlainObject(data)) { _Object$keys(data).forEach(function (key) { var val = data[key]; if (_util.isPromise(val)) { promises.push(val.then(function (resolvedVal) { component.$set(key, resolvedVal); })); } else { component.$set(key, val); } }); } if (!promises.length) { component.$loadingRouteData = false; cb && cb(); } else { promises[0].constructor.all(promises).then(function (_) { component.$loadingRouteData = false; cb && cb(); }, onError); } }, { cleanup: cleanup, expectData: true }); } function isPlainObject(obj) { return Object.prototype.toString.call(obj) === '[object Object]'; } /***/ }, /* 20 */ /***/ function(module, exports, __webpack_require__) { module.exports = { "default": __webpack_require__(21), __esModule: true }; /***/ }, /* 21 */ /***/ function(module, exports, __webpack_require__) { __webpack_require__(22); module.exports = __webpack_require__(16).Object.keys; /***/ }, /* 22 */ /***/ function(module, exports, __webpack_require__) { // 19.1.2.14 Object.keys(O) var toObject = __webpack_require__(23); __webpack_require__(13)('keys', function($keys){ return function keys(it){ return $keys(toObject(it)); }; }); /***/ }, /* 23 */ /***/ function(module, exports, __webpack_require__) { // 7.1.13 ToObject(argument) var defined = __webpack_require__(24); module.exports = function(it){ return Object(defined(it)); }; /***/ }, /* 24 */ /***/ function(module, exports) { // 7.2.1 RequireObjectCoercible(argument) module.exports = function(it){ if(it == undefined)throw TypeError("Can't call method on " + it); return it; }; /***/ }, /* 25 */ /***/ function(module, exports, __webpack_require__) { module.exports = { "default": __webpack_require__(26), __esModule: true }; /***/ }, /* 26 */ /***/ function(module, exports, __webpack_require__) { var $ = __webpack_require__(27); module.exports = function create(P, D){ return $.create(P, D); }; /***/ }, /* 27 */ /***/ function(module, exports) { var $Object = Object; module.exports = { create: $Object.create, getProto: $Object.getPrototypeOf, isEnum: {}.propertyIsEnumerable, getDesc: $Object.getOwnPropertyDescriptor, setDesc: $Object.defineProperty, setDescs: $Object.defineProperties, getKeys: $Object.keys, getNames: $Object.getOwnPropertyNames, getSymbols: $Object.getOwnPropertySymbols, each: [].forEach }; /***/ }, /* 28 */ /***/ function(module, exports, __webpack_require__) { 'use strict'; exports.__esModule = true; var _util = __webpack_require__(3); var _pipeline = __webpack_require__(19); exports['default'] = function (Vue) { var _ = Vue.util; var componentDef = // 0.12 Vue.directive('_component') || // 1.0 Vue.internalDirectives.component; // <router-view> extends the internal component directive var viewDef = _.extend({}, componentDef); // with some overrides _.extend(viewDef, { _isRouterView: true, bind: function bind() { var route = this.vm.$route; /* istanbul ignore if */ if (!route) { _util.warn('<router-view> can only be used inside a ' + 'router-enabled app.'); return; } // force dynamic directive so v-component doesn't // attempt to build right now this._isDynamicLiteral = true; // finally, init by delegating to v-component componentDef.bind.call(this); // all we need to do here is registering this view // in the router. actual component switching will be // managed by the pipeline. var router = this.router = route.router; router._views.unshift(this); // note the views are in reverse order. var parentView = router._views[1]; if (parentView) { // register self as a child of the parent view, // instead of activating now. This is so that the // child's activate hook is called after the // parent's has resolved. parentView.childView = this; } // handle late-rendered view // two possibilities: // 1. root view rendered after transition has been // validated; // 2. child view rendered after parent view has been // activated. var transition = route.router._currentTransition; if (!parentView && transition.done || parentView && parentView.activated) { var depth = parentView ? parentView.depth + 1 : 0; _pipeline.activate(this, transition, depth); } }, unbind: function unbind() { this.router._views.$remove(this); componentDef.unbind.call(this); } }); Vue.elementDirective('router-view', viewDef); }; module.exports = exports['default']; /***/ }, /* 29 */ /***/ function(module, exports, __webpack_require__) { 'use strict'; exports.__esModule = true; var _util = __webpack_require__(3); var trailingSlashRE = /\/$/; var regexEscapeRE = /[-.*+?^${}()|[\]\/\\]/g; // install v-link, which provides navigation support for // HTML5 history mode exports['default'] = function (Vue) { var _ = Vue.util; Vue.directive('link', { bind: function bind() { var _this = this; var vm = this.vm; /* istanbul ignore if */ if (!vm.$route) { _util.warn('v-link can only be used inside a ' + 'router-enabled app.'); return; } var router = vm.$route.router; this.handler = function (e) { // don't redirect with control keys if (e.metaKey || e.ctrlKey || e.shiftKey) return; // don't redirect when preventDefault called if (e.defaultPrevented) return; // don't redirect on right click if (e.button !== 0) return; var target = _this.target; var go = function go(target) { e.preventDefault(); if (target != null) { router.go(target); } }; if (_this.el.tagName === 'A' || e.target === _this.el) { // v-link on <a v-link="'path'"> go(target); } else { // v-link delegate on <div v-link> var el = e.target; while (el && el.tagName !== 'A' && el !== _this.el) { el = el.parentNode; } if (!el) return; if (el.tagName !== 'A' || !el.href) { // allow not anchor go(target); } else if (sameOrigin(el)) { go({ path: el.pathname, replace: target && target.replace, append: target && target.append }); } } }; this.el.addEventListener('click', this.handler); // manage active link class this.unwatch = vm.$watch('$route.path', _.bind(this.updateClasses, this)); }, update: function update(path) { var router = this.vm.$route.router; var append = undefined; this.target = path; if (_.isObject(path)) { append = path.append; this.exact = path.exact; this.prevActiveClass = this.activeClass; this.activeClass = path.activeClass; } path = this.path = router._stringifyPath(path); this.activeRE = path && !this.exact ? new RegExp('^' + path.replace(/\/$/, '').replace(regexEscapeRE, '\\$&') + '(\\/|$)') : null; this.updateClasses(this.vm.$route.path); var isAbsolute = path.charAt(0) === '/'; // do not format non-hash relative paths var href = path && (router.mode === 'hash' || isAbsolute) ? router.history.formatPath(path, append) : path; if (this.el.tagName === 'A') { if (href) { this.el.href = href; } else { this.el.removeAttribute('href'); } } }, updateClasses: function updateClasses(path) { var el = this.el; var dest = this.path; var router = this.vm.$route.router; var activeClass = this.activeClass || router._linkActiveClass; // clear old class if (this.prevActiveClass !== activeClass) { _.removeClass(el, this.prevActiveClass); } // add new class if (this.exact) { if (dest === path || // also allow additional trailing slash dest.charAt(dest.length - 1) !== '/' && dest === path.replace(trailingSlashRE, '')) { _.addClass(el, activeClass); } else { _.removeClass(el, activeClass); } } else { if (this.activeRE && this.activeRE.test(path)) { _.addClass(el, activeClass); } else { _.removeClass(el, activeClass); } } }, unbind: function unbind() { this.el.removeEventListener('click', this.handler); this.unwatch && this.unwatch(); } }); function sameOrigin(link) { return link.protocol === location.protocol && link.hostname === location.hostname && link.port === location.port; } }; module.exports = exports['default']; /***/ }, /* 30 */ /***/ function(module, exports, __webpack_require__) { 'use strict'; var _classCallCheck = __webpack_require__(1)['default']; exports.__esModule = true; var _util = __webpack_require__(3); var AbstractHistory = (function () { function AbstractHistory(_ref) { var onChange = _ref.onChange; _classCallCheck(this, AbstractHistory); this.onChange = onChange; this.currentPath = '/'; } AbstractHistory.prototype.start = function start() { this.onChange('/'); }; AbstractHistory.prototype.stop = function stop() { // noop }; AbstractHistory.prototype.go = function go(path, replace, append) { path = this.currentPath = this.formatPath(path, append); this.onChange(path); }; AbstractHistory.prototype.formatPath = function formatPath(path, append) { return path.charAt(0) === '/' ? path : _util.resolvePath(this.currentPath, path, append); }; return AbstractHistory; })(); exports['default'] = AbstractHistory; module.exports = exports['default']; /***/ }, /* 31 */ /***/ function(module, exports, __webpack_require__) { 'use strict'; var _classCallCheck = __webpack_require__(1)['default']; exports.__esModule = true; var _util = __webpack_require__(3); var HashHistory = (function () { function HashHistory(_ref) { var hashbang = _ref.hashbang; var onChange = _ref.onChange; _classCallCheck(this, HashHistory); this.hashbang = hashbang; this.onChange = onChange; } HashHistory.prototype.start = function start() { var self = this; this.listener = function () { var path = location.hash; var raw = path.replace(/^#!?/, ''); // always if (raw.charAt(0) !== '/') { raw = '/' + raw; } var formattedPath = self.formatPath(raw); if (formattedPath !== path) { location.replace(formattedPath); return; } var pathToMatch = decodeURI(path.replace(/^#!?/, '') + location.search); self.onChange(pathToMatch); }; window.addEventListener('hashchange', this.listener); this.listener(); }; HashHistory.prototype.stop = function stop() { window.removeEventListener('hashchange', this.listener); }; HashHistory.prototype.go = function go(path, replace, append) { path = this.formatPath(path, append); if (replace) { location.replace(path); } else { location.hash = path; } }; HashHistory.prototype.formatPath = function formatPath(path, append) { var isAbsoloute = path.charAt(0) === '/'; var prefix = '#' + (this.hashbang ? '!' : ''); return isAbsoloute ? prefix + path : prefix + _util.resolvePath(location.hash.replace(/^#!?/, ''), path, append); }; return HashHistory; })(); exports['default'] = HashHistory; module.exports = exports['default']; /***/ }, /* 32 */ /***/ function(module, exports, __webpack_require__) { 'use strict'; var _classCallCheck = __webpack_require__(1)['default']; exports.__esModule = true; var _util = __webpack_require__(3); var hashRE = /#.*$/; var HTML5History = (function () { function HTML5History(_ref) { var root = _ref.root; var onChange = _ref.onChange; _classCallCheck(this, HTML5History); if (root) { // make sure there's the starting slash if (root.charAt(0) !== '/') { root = '/' + root; } // remove trailing slash this.root = root.replace(/\/$/, ''); this.rootRE = new RegExp('^\\' + this.root); } else { this.root = null; } this.onChange = onChange; // check base tag var baseEl = document.querySelector('base'); this.base = baseEl && baseEl.getAttribute('href'); } HTML5History.prototype.start = function start() { var _this = this; this.listener = function (e) { var url = decodeURI(location.pathname + location.search); if (_this.root) { url = url.replace(_this.rootRE, ''); } _this.onChange(url, e && e.state, location.hash); }; window.addEventListener('popstate', this.listener); this.listener(); }; HTML5History.prototype.stop = function stop() { window.removeEventListener('popstate', this.listener); }; HTML5History.prototype.go = function go(path, replace, append) { var url = this.formatPath(path, append); if (replace) { history.replaceState({}, '', url); } else { // record scroll position by replacing current state history.replaceState({ pos: { x: window.pageXOffset, y: window.pageYOffset } }, ''); // then push new state history.pushState({}, '', url); } var hashMatch = path.match(hashRE); var hash = hashMatch && hashMatch[0]; path = url // strip hash so it doesn't mess up params .replace(hashRE, '') // remove root before matching .replace(this.rootRE, ''); this.onChange(path, null, hash); }; HTML5History.prototype.formatPath = function formatPath(path, append) { return path.charAt(0) === '/' // absolute path ? this.root ? this.root + '/' + path.replace(/^\//, '') : path : _util.resolvePath(this.base || location.pathname, path, append); }; return HTML5History; })(); exports['default'] = HTML5History; module.exports = exports['default']; /***/ } /******/ ]) }); ;