|
1 | 1 | /*!
|
2 |
| - * vue-router v0.7.9 |
| 2 | + * vue-router v0.7.10 |
3 | 3 | * (c) 2016 Evan You
|
4 | 4 | * Released under the MIT License.
|
5 | 5 | */
|
|
182 | 182 | },
|
183 | 183 |
|
184 | 184 | generate: function generate(params) {
|
185 |
| - return params[this.name] || ":" + this.name; |
| 185 | + var val = params[this.name]; |
| 186 | + return val == null ? ":" + this.name : val; |
186 | 187 | }
|
187 | 188 | };
|
188 | 189 |
|
|
199 | 200 | },
|
200 | 201 |
|
201 | 202 | generate: function generate(params) {
|
202 |
| - return params[this.name] || ":" + this.name; |
| 203 | + var val = params[this.name]; |
| 204 | + return val == null ? ":" + this.name : val; |
203 | 205 | }
|
204 | 206 | };
|
205 | 207 |
|
|
1118 | 1120 | function activate(view, transition, depth, cb, reuse) {
|
1119 | 1121 | var handler = transition.activateQueue[depth];
|
1120 | 1122 | if (!handler) {
|
1121 |
| - // fix 1.0.0-alpha.3 compat |
| 1123 | + saveChildView(view); |
1122 | 1124 | if (view._bound) {
|
1123 | 1125 | view.setComponent(null);
|
1124 | 1126 | }
|
|
1148 | 1150 | component = view.childVM;
|
1149 | 1151 | component.$loadingRouteData = loading;
|
1150 | 1152 | } else {
|
| 1153 | + saveChildView(view); |
| 1154 | + |
1151 | 1155 | // unbuild current component. this step also destroys
|
1152 | 1156 | // and removes all nested child views.
|
1153 | 1157 | view.unbuild(true);
|
1154 | 1158 |
|
1155 |
| - // handle keep-alive. |
1156 |
| - // cache the child view on the kept-alive child vm. |
1157 |
| - if (view.keepAlive && view.childVM && view.childView) { |
1158 |
| - view.childVM._keepAliveRouterView = view.childView; |
1159 |
| - } |
1160 |
| - |
1161 | 1159 | // build the new component. this will also create the
|
1162 | 1160 | // direct child view of the current one. it will register
|
1163 | 1161 | // itself as view.childView.
|
|
1214 | 1212 | cb && cb();
|
1215 | 1213 | };
|
1216 | 1214 |
|
1217 |
| - // called after activation hook is resolved |
1218 |
| - var afterActivate = function afterActivate() { |
1219 |
| - view.activated = true; |
| 1215 | + var afterData = function afterData() { |
1220 | 1216 | // activate the child view
|
1221 | 1217 | if (view.childView) {
|
1222 | 1218 | activate(view.childView, transition, depth + 1, null, reuse || view.keepAlive);
|
1223 | 1219 | }
|
| 1220 | + insert(); |
| 1221 | + }; |
| 1222 | + |
| 1223 | + // called after activation hook is resolved |
| 1224 | + var afterActivate = function afterActivate() { |
| 1225 | + view.activated = true; |
1224 | 1226 | if (dataHook && waitForData) {
|
1225 | 1227 | // wait until data loaded to insert
|
1226 |
| - loadData(component, transition, dataHook, insert, cleanup); |
| 1228 | + loadData(component, transition, dataHook, afterData, cleanup); |
1227 | 1229 | } else {
|
1228 | 1230 | // load data and insert at the same time
|
1229 | 1231 | if (dataHook) {
|
1230 | 1232 | loadData(component, transition, dataHook);
|
1231 | 1233 | }
|
1232 |
| - insert(); |
| 1234 | + afterData(); |
1233 | 1235 | }
|
1234 | 1236 | };
|
1235 | 1237 |
|
1236 | 1238 | if (activateHook) {
|
1237 |
| - transition.callHooks(activateHook, component, afterActivate, { |
1238 |
| - cleanup: cleanup |
1239 |
| - }); |
| 1239 | + transition.callHooks(activateHook, component, afterActivate, { cleanup: cleanup }); |
1240 | 1240 | } else {
|
1241 | 1241 | afterActivate();
|
1242 | 1242 | }
|
|
1300 | 1300 | component.$emit('route-data-loaded', component);
|
1301 | 1301 | cb && cb();
|
1302 | 1302 | } else {
|
1303 |
| - promises[0].constructor.all(promises).then(function (_) { |
| 1303 | + promises[0].constructor.all(promises).then(function () { |
1304 | 1304 | component.$loadingRouteData = false;
|
1305 | 1305 | component.$emit('route-data-loaded', component);
|
1306 | 1306 | cb && cb();
|
|
1312 | 1312 | });
|
1313 | 1313 | }
|
1314 | 1314 |
|
1315 |
| - function isPlainObject(obj) { |
1316 |
| - return Object.prototype.toString.call(obj) === '[object Object]'; |
| 1315 | + /** |
| 1316 | + * Save the child view for a kept-alive view so that |
| 1317 | + * we can restore it when it is switched back to. |
| 1318 | + * |
| 1319 | + * @param {Directive} view |
| 1320 | + */ |
| 1321 | + |
| 1322 | + function saveChildView(view) { |
| 1323 | + if (view.keepAlive && view.childVM && view.childView) { |
| 1324 | + view.childVM._keepAliveRouterView = view.childView; |
| 1325 | + } |
| 1326 | + view.childView = null; |
| 1327 | + } |
| 1328 | + |
| 1329 | + /** |
| 1330 | + * Check plain object. |
| 1331 | + * |
| 1332 | + * @param {*} val |
| 1333 | + */ |
| 1334 | + |
| 1335 | + function isPlainObject(val) { |
| 1336 | + return Object.prototype.toString.call(val) === '[object Object]'; |
1317 | 1337 | }
|
1318 | 1338 |
|
1319 | 1339 | /**
|
|
1706 | 1726 |
|
1707 | 1727 | var destroy = Vue.prototype._destroy;
|
1708 | 1728 | Vue.prototype._destroy = function () {
|
1709 |
| - if (!this._isBeingDestroyed) { |
1710 |
| - if (this.$router) { |
1711 |
| - this.$router._children.$remove(this); |
1712 |
| - } |
1713 |
| - destroy.apply(this, arguments); |
| 1729 | + if (!this._isBeingDestroyed && this.$router) { |
| 1730 | + this.$router._children.$remove(this); |
1714 | 1731 | }
|
| 1732 | + destroy.apply(this, arguments); |
1715 | 1733 | };
|
1716 | 1734 |
|
1717 | 1735 | // 1.0 only: enable route mixins
|
|
1849 | 1867 | this.router = vm.$route.router;
|
1850 | 1868 | // update things when the route changes
|
1851 | 1869 | this.unwatch = vm.$watch('$route', _bind(this.onRouteUpdate, this));
|
1852 |
| - // no need to handle click if link expects to be opened |
1853 |
| - // in a new window/tab. |
1854 |
| - /* istanbul ignore if */ |
1855 |
| - if (this.el.tagName === 'A' && this.el.getAttribute('target') === '_blank') { |
1856 |
| - return; |
1857 |
| - } |
1858 |
| - // handle click |
1859 |
| - this.el.addEventListener('click', _bind(this.onClick, this)); |
1860 | 1870 | // check if active classes should be applied to a different element
|
1861 | 1871 | this.activeEl = this.el;
|
1862 | 1872 | var parent = this.el.parentNode;
|
|
1867 | 1877 | }
|
1868 | 1878 | parent = parent.parentNode;
|
1869 | 1879 | }
|
| 1880 | + // no need to handle click if link expects to be opened |
| 1881 | + // in a new window/tab. |
| 1882 | + /* istanbul ignore if */ |
| 1883 | + if (this.el.tagName === 'A' && this.el.getAttribute('target') === '_blank') { |
| 1884 | + return; |
| 1885 | + } |
| 1886 | + // handle click |
| 1887 | + this.el.addEventListener('click', _bind(this.onClick, this)); |
1870 | 1888 | },
|
1871 | 1889 |
|
1872 | 1890 | update: function update(target) {
|
|
2001 | 2019 |
|
2002 | 2020 | var Router = (function () {
|
2003 | 2021 | function Router() {
|
| 2022 | + var _this = this; |
| 2023 | + |
2004 | 2024 | var _ref = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
|
2005 | 2025 |
|
2006 | 2026 | var _ref$hashbang = _ref.hashbang;
|
|
2045 | 2065 | this._beforeEachHooks = [];
|
2046 | 2066 | this._afterEachHooks = [];
|
2047 | 2067 |
|
2048 |
| - // feature detection |
2049 |
| - this._hasPushState = typeof window !== 'undefined' && window.history && window.history.pushState; |
2050 |
| - |
2051 | 2068 | // trigger transition on initial render?
|
2052 | 2069 | this._rendered = false;
|
2053 | 2070 | this._transitionOnLoad = transitionOnLoad;
|
2054 | 2071 |
|
2055 | 2072 | // history mode
|
| 2073 | + this._root = root; |
2056 | 2074 | this._abstract = abstract;
|
2057 | 2075 | this._hashbang = hashbang;
|
2058 |
| - this._history = this._hasPushState && history; |
2059 | 2076 |
|
2060 |
| - // other options |
2061 |
| - this._saveScrollPosition = saveScrollPosition; |
2062 |
| - this._linkActiveClass = linkActiveClass; |
2063 |
| - this._suppress = suppressTransitionError; |
| 2077 | + // check if HTML5 history is available |
| 2078 | + var hasPushState = typeof window !== 'undefined' && window.history && window.history.pushState; |
| 2079 | + this._history = history && hasPushState; |
| 2080 | + this._historyFallback = history && !hasPushState; |
2064 | 2081 |
|
2065 | 2082 | // create history object
|
2066 | 2083 | var inBrowser = Vue.util.inBrowser;
|
2067 | 2084 | this.mode = !inBrowser || this._abstract ? 'abstract' : this._history ? 'html5' : 'hash';
|
2068 | 2085 |
|
2069 | 2086 | var History = historyBackends[this.mode];
|
2070 |
| - var self = this; |
2071 | 2087 | this.history = new History({
|
2072 | 2088 | root: root,
|
2073 | 2089 | hashbang: this._hashbang,
|
2074 | 2090 | onChange: function onChange(path, state, anchor) {
|
2075 |
| - self._match(path, state, anchor); |
| 2091 | + _this._match(path, state, anchor); |
2076 | 2092 | }
|
2077 | 2093 | });
|
| 2094 | + |
| 2095 | + // other options |
| 2096 | + this._saveScrollPosition = saveScrollPosition; |
| 2097 | + this._linkActiveClass = linkActiveClass; |
| 2098 | + this._suppress = suppressTransitionError; |
2078 | 2099 | }
|
2079 | 2100 |
|
2080 | 2101 | /**
|
|
2237 | 2258 | // give it a name for better debugging
|
2238 | 2259 | Ctor.options.name = Ctor.options.name || 'RouterApp';
|
2239 | 2260 | }
|
| 2261 | + |
| 2262 | + // handle history fallback in browsers that do not |
| 2263 | + // support HTML5 history API |
| 2264 | + if (this._historyFallback) { |
| 2265 | + var _location = window.location; |
| 2266 | + var _history = new HTML5History({ root: this._root }); |
| 2267 | + var path = _history.root ? _location.pathname.replace(_history.rootRE, '') : _location.pathname; |
| 2268 | + if (path && path !== '/') { |
| 2269 | + _location.assign((_history.root || '') + '/' + this.history.formatPath(path) + _location.search); |
| 2270 | + return; |
| 2271 | + } |
| 2272 | + } |
| 2273 | + |
2240 | 2274 | this.history.start();
|
2241 | 2275 | };
|
2242 | 2276 |
|
|
2332 | 2366 | */
|
2333 | 2367 |
|
2334 | 2368 | Router.prototype._addGuard = function _addGuard(path, mappedPath, _handler) {
|
2335 |
| - var _this = this; |
| 2369 | + var _this2 = this; |
2336 | 2370 |
|
2337 | 2371 | this._guardRecognizer.add([{
|
2338 | 2372 | path: path,
|
2339 | 2373 | handler: function handler(match, query) {
|
2340 | 2374 | var realPath = mapParams(mappedPath, match.params, query);
|
2341 |
| - _handler.call(_this, realPath); |
| 2375 | + _handler.call(_this2, realPath); |
2342 | 2376 | }
|
2343 | 2377 | }]);
|
2344 | 2378 | };
|
|
2374 | 2408 | */
|
2375 | 2409 |
|
2376 | 2410 | Router.prototype._match = function _match(path, state, anchor) {
|
2377 |
| - var _this2 = this; |
| 2411 | + var _this3 = this; |
2378 | 2412 |
|
2379 | 2413 | if (this._checkGuard(path)) {
|
2380 | 2414 | return;
|
|
2413 | 2447 | if (!this.app) {
|
2414 | 2448 | (function () {
|
2415 | 2449 | // initial render
|
2416 |
| - var router = _this2; |
2417 |
| - _this2.app = new _this2._appConstructor({ |
2418 |
| - el: _this2._appContainer, |
| 2450 | + var router = _this3; |
| 2451 | + _this3.app = new _this3._appConstructor({ |
| 2452 | + el: _this3._appContainer, |
2419 | 2453 | created: function created() {
|
2420 | 2454 | this.$router = router;
|
2421 | 2455 | },
|
|
2430 | 2464 | var beforeHooks = this._beforeEachHooks;
|
2431 | 2465 | var startTransition = function startTransition() {
|
2432 | 2466 | transition.start(function () {
|
2433 |
| - _this2._postTransition(route, state, anchor); |
| 2467 | + _this3._postTransition(route, state, anchor); |
2434 | 2468 | });
|
2435 | 2469 | };
|
2436 | 2470 |
|
2437 | 2471 | if (beforeHooks.length) {
|
2438 | 2472 | transition.runQueue(beforeHooks, function (hook, _, next) {
|
2439 |
| - if (transition === _this2._currentTransition) { |
| 2473 | + if (transition === _this3._currentTransition) { |
2440 | 2474 | transition.callHook(hook, null, next, {
|
2441 | 2475 | expectBoolean: true
|
2442 | 2476 | });
|
|
2523 | 2557 | */
|
2524 | 2558 |
|
2525 | 2559 | Router.prototype._stringifyPath = function _stringifyPath(path) {
|
| 2560 | + var fullPath = ''; |
2526 | 2561 | if (path && typeof path === 'object') {
|
2527 | 2562 | if (path.name) {
|
2528 | 2563 | var extend = Vue.util.extend;
|
|
2532 | 2567 | if (path.query) {
|
2533 | 2568 | params.queryParams = path.query;
|
2534 | 2569 | }
|
2535 |
| - return this._recognizer.generate(path.name, params); |
| 2570 | + fullPath = this._recognizer.generate(path.name, params); |
2536 | 2571 | } else if (path.path) {
|
2537 |
| - var fullPath = path.path; |
| 2572 | + fullPath = path.path; |
2538 | 2573 | if (path.query) {
|
2539 | 2574 | var query = this._recognizer.generateQueryString(path.query);
|
2540 | 2575 | if (fullPath.indexOf('?') > -1) {
|
|
2543 | 2578 | fullPath += query;
|
2544 | 2579 | }
|
2545 | 2580 | }
|
2546 |
| - return fullPath; |
2547 |
| - } else { |
2548 |
| - return ''; |
2549 | 2581 | }
|
2550 | 2582 | } else {
|
2551 |
| - return path ? path + '' : ''; |
| 2583 | + fullPath = path ? path + '' : ''; |
2552 | 2584 | }
|
| 2585 | + return encodeURI(fullPath); |
2553 | 2586 | };
|
2554 | 2587 |
|
2555 | 2588 | return Router;
|
|
0 commit comments