/*! * 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 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 " + 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 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 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; // 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(' 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 go(target); } else { // v-link delegate on
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']; /***/ } /******/ ]) }); ;