|
185 | 185 | return true
|
186 | 186 | }
|
187 | 187 |
|
188 |
| - function assert (condition, message) { |
| 188 | + /* */ |
| 189 | + |
| 190 | + function assert (condition , message ) { |
189 | 191 | if (!condition) {
|
190 | 192 | throw new Error(("[vue-router] " + message))
|
191 | 193 | }
|
192 | 194 | }
|
193 | 195 |
|
194 |
| - function warn (condition, message) { |
| 196 | + function warn (condition , message ) { |
195 | 197 | if (!condition) {
|
196 | 198 | typeof console !== 'undefined' && console.warn(("[vue-router] " + message))
|
197 | 199 | }
|
|
404 | 406 | beforeCreate: function beforeCreate () {
|
405 | 407 | if (this.$options.router) {
|
406 | 408 | this._router = this.$options.router
|
407 |
| - this._router.app = this |
| 409 | + this._router.init(this) |
408 | 410 | Vue.util.defineReactive(this, '_route', this._router.history.current)
|
409 | 411 | }
|
410 | 412 | }
|
|
1034 | 1036 | hash: hash
|
1035 | 1037 | }, undefined, location)
|
1036 | 1038 | } else {
|
1037 |
| - warn(("invalid redirect option: " + (JSON.stringify(redirect)))) |
| 1039 | + warn(false, ("invalid redirect option: " + (JSON.stringify(redirect)))) |
1038 | 1040 | return createRouteContext(null, location)
|
1039 | 1041 | }
|
1040 | 1042 | }
|
|
1104 | 1106 | (regexpCompileCache[path] = Regexp.compile(path))
|
1105 | 1107 | return filler(params || {}, { pretty: true })
|
1106 | 1108 | } catch (e) {
|
1107 |
| - assert(("missing param for " + routeMsg + ": " + (e.message))) |
| 1109 | + assert(false, ("missing param for " + routeMsg + ": " + (e.message))) |
1108 | 1110 | return ''
|
1109 | 1111 | }
|
1110 | 1112 | }
|
|
1201 | 1203 | // deactivate guards
|
1202 | 1204 | extractLeaveGuards(deactivated),
|
1203 | 1205 | // global before hooks
|
1204 |
| - nomralizeGuards(this.router.options.beforeEach), |
| 1206 | + this.router.beforeHooks, |
1205 | 1207 | // activate guards
|
1206 | 1208 | activated.map(function (m) { return m.beforeEnter; })
|
1207 | 1209 | ).filter(function (_) { return _; })
|
|
1224 | 1226 | History.prototype.updateRoute = function updateRoute (route ) {
|
1225 | 1227 | this.current = route
|
1226 | 1228 | this.cb && this.cb(route)
|
1227 |
| - nomralizeGuards(this.router.options.afterEach).forEach(function (hook) { |
| 1229 | + this.router.afterHooks.forEach(function (hook) { |
1228 | 1230 | hook && hook(route)
|
1229 | 1231 | })
|
1230 | 1232 | };
|
|
1271 | 1273 | }
|
1272 | 1274 | }
|
1273 | 1275 |
|
1274 |
| - function nomralizeGuards (guards ) { |
1275 |
| - if (!guards) { |
1276 |
| - return [] |
1277 |
| - } |
1278 |
| - if (typeof guards === 'function') { |
1279 |
| - return [guards] |
1280 |
| - } |
1281 |
| - return guards |
1282 |
| - } |
1283 |
| - |
1284 | 1276 | function extractLeaveGuards (matched ) {
|
1285 | 1277 | return Array.prototype.concat.apply([], matched.map(function (m) {
|
1286 | 1278 | return Object.keys(m.components).map(function (key) {
|
|
1298 | 1290 | }).reverse())
|
1299 | 1291 | }
|
1300 | 1292 |
|
| 1293 | + /* */ |
| 1294 | + |
| 1295 | + function saveScrollPosition (key ) { |
| 1296 | + if (!key) return |
| 1297 | + window.sessionStorage.setItem(key, JSON.stringify({ |
| 1298 | + x: window.pageXOffset, |
| 1299 | + y: window.pageYOffset |
| 1300 | + })) |
| 1301 | + } |
| 1302 | + |
| 1303 | + function getScrollPosition (key ) { |
| 1304 | + if (!key) return |
| 1305 | + return JSON.parse(window.sessionStorage.getItem(key)) |
| 1306 | + } |
| 1307 | + |
| 1308 | + function getElementPosition (el ) { |
| 1309 | + var docRect = document.documentElement.getBoundingClientRect() |
| 1310 | + var elRect = el.getBoundingClientRect() |
| 1311 | + return { |
| 1312 | + x: elRect.left - docRect.left, |
| 1313 | + y: elRect.top - docRect.top |
| 1314 | + } |
| 1315 | + } |
| 1316 | + |
| 1317 | + function isValidPosition (obj ) { |
| 1318 | + return isNumber(obj.x) || isNumber(obj.y) |
| 1319 | + } |
| 1320 | + |
| 1321 | + function normalizePosotion (obj ) { |
| 1322 | + return { |
| 1323 | + x: isNumber(obj.x) ? obj.x : window.pageXOffset, |
| 1324 | + y: isNumber(obj.y) ? obj.y : window.pageYOffset |
| 1325 | + } |
| 1326 | + } |
| 1327 | + |
| 1328 | + function isNumber (v ) { |
| 1329 | + return typeof v === 'number' |
| 1330 | + } |
| 1331 | + |
1301 | 1332 | var genKey = function () { return String(Date.now()); }
|
1302 | 1333 | var _key = genKey()
|
1303 | 1334 |
|
|
1326 | 1357 | })
|
1327 | 1358 |
|
1328 | 1359 | if (expectScroll) {
|
1329 |
| - window.addEventListener('scroll', saveScrollPosition) |
| 1360 | + window.addEventListener('scroll', function () { |
| 1361 | + saveScrollPosition(_key) |
| 1362 | + }) |
1330 | 1363 | }
|
1331 | 1364 | }
|
1332 | 1365 |
|
|
1372 | 1405 | if (!behavior) {
|
1373 | 1406 | return
|
1374 | 1407 | }
|
1375 |
| - |
1376 | 1408 | assert(typeof behavior === 'function', "scrollBehavior must be a function")
|
1377 | 1409 |
|
1378 |
| - var position = getScrollPosition() |
1379 |
| - var shouldScroll = behavior(to, from, isPop ? position : null) |
1380 |
| - if (!shouldScroll) { |
1381 |
| - return |
1382 |
| - } |
1383 |
| - |
1384 | 1410 | // wait until re-render finishes before scrolling
|
1385 | 1411 | router.app.$nextTick(function () {
|
| 1412 | + var position = getScrollPosition(_key) |
| 1413 | + var shouldScroll = behavior(to, from, isPop ? position : null) |
| 1414 | + if (!shouldScroll) { |
| 1415 | + return |
| 1416 | + } |
1386 | 1417 | var isObject = typeof shouldScroll === 'object'
|
1387 |
| - if (isObject && shouldScroll.x != null && shouldScroll.y != null) { |
1388 |
| - position = shouldScroll |
1389 |
| - } else if (isObject && shouldScroll.anchor) { |
1390 |
| - var el = document.querySelector(to.hash) |
| 1418 | + if (isObject && shouldScroll.selector) { |
| 1419 | + var el = document.querySelector(shouldScroll.selector) |
1391 | 1420 | if (el) {
|
1392 |
| - var docTop = document.documentElement.getBoundingClientRect().top |
1393 |
| - var elTop = el.getBoundingClientRect().top |
1394 |
| - position = { |
1395 |
| - x: window.scrollX, |
1396 |
| - y: elTop - docTop |
1397 |
| - } |
| 1421 | + position = getElementPosition(el) |
| 1422 | + } else if (isValidPosition(shouldScroll)) { |
| 1423 | + position = normalizePosotion(shouldScroll) |
1398 | 1424 | }
|
| 1425 | + } else if (isObject && isValidPosition(shouldScroll)) { |
| 1426 | + position = normalizePosotion(shouldScroll) |
1399 | 1427 | }
|
1400 | 1428 |
|
1401 | 1429 | if (position) {
|
|
1426 | 1454 | _key = genKey()
|
1427 | 1455 | history.pushState({ key: _key }, '', url)
|
1428 | 1456 | }
|
1429 |
| - saveScrollPosition() |
| 1457 | + saveScrollPosition(_key) |
1430 | 1458 | } catch (e) {
|
1431 | 1459 | window.location[replace ? 'assign' : 'replace'](url)
|
1432 | 1460 | }
|
|
1436 | 1464 | pushState(url, true)
|
1437 | 1465 | }
|
1438 | 1466 |
|
1439 |
| - function saveScrollPosition () { |
1440 |
| - if (!_key) return |
1441 |
| - window.sessionStorage.setItem(_key, JSON.stringify({ |
1442 |
| - x: window.pageXOffset, |
1443 |
| - y: window.pageYOffset |
1444 |
| - })) |
1445 |
| - } |
1446 |
| - |
1447 |
| - function getScrollPosition () { |
1448 |
| - if (!_key) return |
1449 |
| - return JSON.parse(window.sessionStorage.getItem(_key)) |
1450 |
| - } |
1451 |
| - |
1452 | 1467 | var HashHistory = (function (History) {
|
1453 | 1468 | function HashHistory (router , base , fallback ) {
|
1454 | 1469 | var this$1 = this;
|
|
1595 | 1610 | }(History));
|
1596 | 1611 |
|
1597 | 1612 | var VueRouter = function VueRouter (options) {
|
1598 |
| - var this$1 = this; |
1599 | 1613 | if ( options === void 0 ) options = {};
|
1600 | 1614 |
|
1601 |
| - assert( |
1602 |
| - install.installed, |
1603 |
| - "not installed. Make sure to call `Vue.use(VueRouter)` " + |
1604 |
| - "before mounting root instance." |
1605 |
| - ) |
1606 |
| - |
1607 | 1615 | this.app = null
|
1608 | 1616 | this.options = options
|
| 1617 | + this.beforeHooks = [] |
| 1618 | + this.afterHooks = [] |
1609 | 1619 | this.match = createMatcher(options.routes || [])
|
1610 | 1620 |
|
1611 | 1621 | var mode = options.mode || 'hash'
|
1612 |
| - var fallback = mode === 'history' && !supportsHistory |
1613 |
| - if (fallback) { |
| 1622 | + this.fallback = mode === 'history' && !supportsHistory |
| 1623 | + if (this.fallback) { |
1614 | 1624 | mode = 'hash'
|
1615 | 1625 | }
|
1616 | 1626 | if (!inBrowser) {
|
1617 | 1627 | mode = 'abstract'
|
1618 | 1628 | }
|
| 1629 | + this.mode = mode |
| 1630 | + }; |
| 1631 | + |
| 1632 | + VueRouter.prototype.init = function init (app /* Vue component instance */) { |
| 1633 | + var this$1 = this; |
| 1634 | + |
| 1635 | + assert( |
| 1636 | + install.installed, |
| 1637 | + "not installed. Make sure to call `Vue.use(VueRouter)` " + |
| 1638 | + "before creating root instance." |
| 1639 | + ) |
1619 | 1640 |
|
| 1641 | + var ref = this; |
| 1642 | + var mode = ref.mode; |
| 1643 | + var options = ref.options; |
| 1644 | + var fallback = ref.fallback; |
1620 | 1645 | switch (mode) {
|
1621 | 1646 | case 'history':
|
1622 | 1647 | this.history = new HTML5History(this, options.base)
|
|
1631 | 1656 | assert(false, ("invalid mode: " + mode))
|
1632 | 1657 | }
|
1633 | 1658 |
|
1634 |
| - this.mode = mode |
1635 |
| - |
| 1659 | + this.app = app |
1636 | 1660 | this.history.listen(function (route) {
|
1637 | 1661 | this$1.app._route = route
|
1638 | 1662 | })
|
1639 | 1663 | };
|
1640 | 1664 |
|
| 1665 | + VueRouter.prototype.beforeEach = function beforeEach (fn ) { |
| 1666 | + this.beforeHooks.push(fn) |
| 1667 | + }; |
| 1668 | + |
| 1669 | + VueRouter.prototype.afterEach = function afterEach (fn ) { |
| 1670 | + this.afterHooks.push(fn) |
| 1671 | + }; |
| 1672 | + |
1641 | 1673 | VueRouter.prototype.push = function push (location ) {
|
1642 | 1674 | this.history.push(location)
|
1643 | 1675 | };
|
1644 | 1676 |
|
1645 | 1677 | VueRouter.prototype.replace = function replace (location ) {
|
1646 | 1678 | this.history.replace(location)
|
1647 |
| - }; |
| 1679 | + }; |
1648 | 1680 |
|
1649 |
| - VueRouter.prototype.go = function go (n ) { |
1650 |
| - this.history.go(n) |
1651 |
| - }; |
| 1681 | + VueRouter.prototype.go = function go (n ) { |
| 1682 | + this.history.go(n) |
| 1683 | + }; |
1652 | 1684 |
|
1653 |
| - VueRouter.prototype.back = function back () { |
| 1685 | + VueRouter.prototype.back = function back () { |
1654 | 1686 | this.go(-1)
|
1655 | 1687 | };
|
1656 | 1688 |
|
|
0 commit comments