vuejs-rails 2.0.8 → 2.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b14ac4b1d7d9e883b4206f5c7559d9be7ab40005
4
- data.tar.gz: 80d3709c219eafee3a329dbace290b31091bd656
3
+ metadata.gz: 16478f016f5826347b878c367ff26308f302f743
4
+ data.tar.gz: 4da439179cae0bb30c41b0c2524c6e36ab82fe54
5
5
  SHA512:
6
- metadata.gz: 11de3fcb8ffba8780d5168d486770d1f69d84efdef0753c59ad032fb7023299f82e1aeb53df33cacb8729951342aaf379d6249a09afc8b4bcb13d18e204e0c4c
7
- data.tar.gz: 537fa5971ef546f6c40f2b3b44a9f99389b9fa142720bfd029f702bb0045a2ce74173419aef1302117dd1ade16b316b804788156cb9e0712388869e0299d982c
6
+ metadata.gz: f12ffd66a5d7f826495d25a6f04ea8c9611af8cd6189a2cc9bae9b0a04a124eee2e1fee20199464f074d69202e925db16b319ef49e66382396cd2c3cba9e743d
7
+ data.tar.gz: 2bef31553724fba5407941397c6976f98fe0ff00873ab1d70fe600d85d19cdf7832adf36cfb6b8e577b13f1a478faaf7bb0f0c2b5aadfeb1259002d54609ef24
data/Readme.md CHANGED
@@ -9,8 +9,8 @@ Rails 3.1+ asset-pipeline gem to provide Vue.js
9
9
 
10
10
  ### Package Versions
11
11
 
12
- - vue v2.0.8
13
- - vue-router v2.0.3
12
+ - vue v2.1.6
13
+ - vue-router v2.1.1
14
14
  - vue-resource v1.0.3
15
15
 
16
16
  ### Setup
@@ -1,5 +1,5 @@
1
1
  module Vue
2
2
  module Rails
3
- VERSION = '2.0.8'
3
+ VERSION = '2.1.6'
4
4
  end
5
5
  end
@@ -1,8 +1,8 @@
1
1
  /**
2
- * vue-router v2.0.3
3
- * (c) 2016 Evan You
4
- * @license MIT
5
- */
2
+ * vue-router v2.1.1
3
+ * (c) 2016 Evan You
4
+ * @license MIT
5
+ */
6
6
  (function (global, factory) {
7
7
  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
8
8
  typeof define === 'function' && define.amd ? define(factory) :
@@ -73,78 +73,6 @@ var View = {
73
73
 
74
74
  /* */
75
75
 
76
- function resolvePath (
77
- relative,
78
- base,
79
- append
80
- ) {
81
- if (relative.charAt(0) === '/') {
82
- return relative
83
- }
84
-
85
- if (relative.charAt(0) === '?' || relative.charAt(0) === '#') {
86
- return base + relative
87
- }
88
-
89
- var stack = base.split('/')
90
-
91
- // remove trailing segment if:
92
- // - not appending
93
- // - appending to trailing slash (last segment is empty)
94
- if (!append || !stack[stack.length - 1]) {
95
- stack.pop()
96
- }
97
-
98
- // resolve relative path
99
- var segments = relative.replace(/^\//, '').split('/')
100
- for (var i = 0; i < segments.length; i++) {
101
- var segment = segments[i]
102
- if (segment === '.') {
103
- continue
104
- } else if (segment === '..') {
105
- stack.pop()
106
- } else {
107
- stack.push(segment)
108
- }
109
- }
110
-
111
- // ensure leading slash
112
- if (stack[0] !== '') {
113
- stack.unshift('')
114
- }
115
-
116
- return stack.join('/')
117
- }
118
-
119
- function parsePath (path) {
120
- var hash = ''
121
- var query = ''
122
-
123
- var hashIndex = path.indexOf('#')
124
- if (hashIndex >= 0) {
125
- hash = path.slice(hashIndex)
126
- path = path.slice(0, hashIndex)
127
- }
128
-
129
- var queryIndex = path.indexOf('?')
130
- if (queryIndex >= 0) {
131
- query = path.slice(queryIndex + 1)
132
- path = path.slice(0, queryIndex)
133
- }
134
-
135
- return {
136
- path: path,
137
- query: query,
138
- hash: hash
139
- }
140
- }
141
-
142
- function cleanPath (path) {
143
- return path.replace(/\/\//g, '/')
144
- }
145
-
146
- /* */
147
-
148
76
  function assert (condition, message) {
149
77
  if (!condition) {
150
78
  throw new Error(("[vue-router] " + message))
@@ -173,7 +101,7 @@ function resolveQuery (
173
101
  try {
174
102
  parsedQuery = parseQuery(query)
175
103
  } catch (e) {
176
- warn(false, e.message)
104
+ "development" !== 'production' && warn(false, e.message)
177
105
  parsedQuery = {}
178
106
  }
179
107
  for (var key in extraQuery) {
@@ -214,7 +142,7 @@ function parseQuery (query) {
214
142
  }
215
143
 
216
144
  function stringifyQuery (obj) {
217
- var res = obj ? Object.keys(obj).sort().map(function (key) {
145
+ var res = obj ? Object.keys(obj).map(function (key) {
218
146
  var val = obj[key]
219
147
 
220
148
  if (val === undefined) {
@@ -345,37 +273,6 @@ function queryIncludes (current, target) {
345
273
 
346
274
  /* */
347
275
 
348
- function normalizeLocation (
349
- raw,
350
- current,
351
- append
352
- ) {
353
- var next = typeof raw === 'string' ? { path: raw } : raw
354
- if (next.name || next._normalized) {
355
- return next
356
- }
357
-
358
- var parsedPath = parsePath(next.path || '')
359
- var basePath = (current && current.path) || '/'
360
- var path = parsedPath.path
361
- ? resolvePath(parsedPath.path, basePath, append)
362
- : (current && current.path) || '/'
363
- var query = resolveQuery(parsedPath.query, next.query)
364
- var hash = next.hash || parsedPath.hash
365
- if (hash && hash.charAt(0) !== '#') {
366
- hash = "#" + hash
367
- }
368
-
369
- return {
370
- _normalized: true,
371
- path: path,
372
- query: query,
373
- hash: hash
374
- }
375
- }
376
-
377
- /* */
378
-
379
276
  // work around weird flow bug
380
277
  var toTypes = [String, Object]
381
278
 
@@ -393,50 +290,45 @@ var Link = {
393
290
  exact: Boolean,
394
291
  append: Boolean,
395
292
  replace: Boolean,
396
- activeClass: String
293
+ activeClass: String,
294
+ event: {
295
+ type: [String, Array],
296
+ default: 'click'
297
+ }
397
298
  },
398
299
  render: function render (h) {
399
300
  var this$1 = this;
400
301
 
401
302
  var router = this.$router
402
303
  var current = this.$route
403
- var to = normalizeLocation(this.to, current, this.append)
404
- var resolved = router.match(to, current)
405
- var fullPath = resolved.redirectedFrom || resolved.fullPath
406
- var base = router.history.base
407
- var href = createHref(base, fullPath, router.mode)
304
+ var ref = router.resolve(this.to, current, this.append);
305
+ var normalizedTo = ref.normalizedTo;
306
+ var resolved = ref.resolved;
307
+ var href = ref.href;
408
308
  var classes = {}
409
309
  var activeClass = this.activeClass || router.options.linkActiveClass || 'router-link-active'
410
- var compareTarget = to.path ? createRoute(null, to) : resolved
310
+ var compareTarget = normalizedTo.path ? createRoute(null, normalizedTo) : resolved
411
311
  classes[activeClass] = this.exact
412
312
  ? isSameRoute(current, compareTarget)
413
313
  : isIncludedRoute(current, compareTarget)
414
314
 
415
- var on = {
416
- click: function (e) {
417
- // don't redirect with control keys
418
- /* istanbul ignore if */
419
- if (e.metaKey || e.ctrlKey || e.shiftKey) { return }
420
- // don't redirect when preventDefault called
421
- /* istanbul ignore if */
422
- if (e.defaultPrevented) { return }
423
- // don't redirect on right click
424
- /* istanbul ignore if */
425
- if (e.button !== 0) { return }
426
- // don't redirect if `target="_blank"`
427
- /* istanbul ignore if */
428
- var target = e.target.getAttribute('target')
429
- if (/\b_blank\b/i.test(target)) { return }
430
-
431
- e.preventDefault()
315
+ var handler = function (e) {
316
+ if (guardEvent(e)) {
432
317
  if (this$1.replace) {
433
- router.replace(to)
318
+ router.replace(normalizedTo)
434
319
  } else {
435
- router.push(to)
320
+ router.push(normalizedTo)
436
321
  }
437
322
  }
438
323
  }
439
324
 
325
+ var on = { click: guardEvent }
326
+ if (Array.isArray(this.event)) {
327
+ this.event.forEach(function (e) { on[e] = handler })
328
+ } else {
329
+ on[this.event] = handler
330
+ }
331
+
440
332
  var data = {
441
333
  class: classes
442
334
  }
@@ -465,6 +357,25 @@ var Link = {
465
357
  }
466
358
  }
467
359
 
360
+ function guardEvent (e) {
361
+ // don't redirect with control keys
362
+ /* istanbul ignore if */
363
+ if (e.metaKey || e.ctrlKey || e.shiftKey) { return }
364
+ // don't redirect when preventDefault called
365
+ /* istanbul ignore if */
366
+ if (e.defaultPrevented) { return }
367
+ // don't redirect on right click
368
+ /* istanbul ignore if */
369
+ if (e.button !== 0) { return }
370
+ // don't redirect if `target="_blank"`
371
+ /* istanbul ignore if */
372
+ var target = e.target.getAttribute('target')
373
+ if (/\b_blank\b/i.test(target)) { return }
374
+
375
+ e.preventDefault()
376
+ return true
377
+ }
378
+
468
379
  function findAnchor (children) {
469
380
  if (children) {
470
381
  var child
@@ -480,11 +391,6 @@ function findAnchor (children) {
480
391
  }
481
392
  }
482
393
 
483
- function createHref (base, fullPath, mode) {
484
- var path = mode === 'hash' ? '/#' + fullPath : fullPath
485
- return base ? cleanPath(base + path) : path
486
- }
487
-
488
394
  var _Vue
489
395
 
490
396
  function install (Vue) {
@@ -519,6 +425,168 @@ function install (Vue) {
519
425
  strats.beforeRouteEnter = strats.beforeRouteLeave = strats.created
520
426
  }
521
427
 
428
+ /* */
429
+
430
+ function resolvePath (
431
+ relative,
432
+ base,
433
+ append
434
+ ) {
435
+ if (relative.charAt(0) === '/') {
436
+ return relative
437
+ }
438
+
439
+ if (relative.charAt(0) === '?' || relative.charAt(0) === '#') {
440
+ return base + relative
441
+ }
442
+
443
+ var stack = base.split('/')
444
+
445
+ // remove trailing segment if:
446
+ // - not appending
447
+ // - appending to trailing slash (last segment is empty)
448
+ if (!append || !stack[stack.length - 1]) {
449
+ stack.pop()
450
+ }
451
+
452
+ // resolve relative path
453
+ var segments = relative.replace(/^\//, '').split('/')
454
+ for (var i = 0; i < segments.length; i++) {
455
+ var segment = segments[i]
456
+ if (segment === '.') {
457
+ continue
458
+ } else if (segment === '..') {
459
+ stack.pop()
460
+ } else {
461
+ stack.push(segment)
462
+ }
463
+ }
464
+
465
+ // ensure leading slash
466
+ if (stack[0] !== '') {
467
+ stack.unshift('')
468
+ }
469
+
470
+ return stack.join('/')
471
+ }
472
+
473
+ function parsePath (path) {
474
+ var hash = ''
475
+ var query = ''
476
+
477
+ var hashIndex = path.indexOf('#')
478
+ if (hashIndex >= 0) {
479
+ hash = path.slice(hashIndex)
480
+ path = path.slice(0, hashIndex)
481
+ }
482
+
483
+ var queryIndex = path.indexOf('?')
484
+ if (queryIndex >= 0) {
485
+ query = path.slice(queryIndex + 1)
486
+ path = path.slice(0, queryIndex)
487
+ }
488
+
489
+ return {
490
+ path: path,
491
+ query: query,
492
+ hash: hash
493
+ }
494
+ }
495
+
496
+ function cleanPath (path) {
497
+ return path.replace(/\/\//g, '/')
498
+ }
499
+
500
+ /* */
501
+
502
+ function createRouteMap (routes) {
503
+ var pathMap = Object.create(null)
504
+ var nameMap = Object.create(null)
505
+
506
+ routes.forEach(function (route) {
507
+ addRouteRecord(pathMap, nameMap, route)
508
+ })
509
+
510
+ return {
511
+ pathMap: pathMap,
512
+ nameMap: nameMap
513
+ }
514
+ }
515
+
516
+ function addRouteRecord (
517
+ pathMap,
518
+ nameMap,
519
+ route,
520
+ parent,
521
+ matchAs
522
+ ) {
523
+ var path = route.path;
524
+ var name = route.name;
525
+ if ("development" !== 'production') {
526
+ assert(path != null, "\"path\" is required in a route configuration.")
527
+ assert(
528
+ typeof route.component !== 'string',
529
+ "route config \"component\" for path: " + (String(path || name)) + " cannot be a " +
530
+ "string id. Use an actual component instead."
531
+ )
532
+ }
533
+
534
+ var record = {
535
+ path: normalizePath(path, parent),
536
+ components: route.components || { default: route.component },
537
+ instances: {},
538
+ name: name,
539
+ parent: parent,
540
+ matchAs: matchAs,
541
+ redirect: route.redirect,
542
+ beforeEnter: route.beforeEnter,
543
+ meta: route.meta || {}
544
+ }
545
+
546
+ if (route.children) {
547
+ // Warn if route is named and has a default child route.
548
+ // If users navigate to this route by name, the default child will
549
+ // not be rendered (GH Issue #629)
550
+ if ("development" !== 'production') {
551
+ if (route.name && route.children.some(function (child) { return /^\/?$/.test(child.path); })) {
552
+ warn(false, ("Named Route '" + (route.name) + "' has a default child route.\n When navigating to this named route (:to=\"{name: '" + (route.name) + "'\"), the default child route will not be rendered.\n Remove the name from this route and use the name of the default child route for named links instead.")
553
+ )
554
+ }
555
+ }
556
+ route.children.forEach(function (child) {
557
+ addRouteRecord(pathMap, nameMap, child, record)
558
+ })
559
+ }
560
+
561
+ if (route.alias !== undefined) {
562
+ if (Array.isArray(route.alias)) {
563
+ route.alias.forEach(function (alias) {
564
+ addRouteRecord(pathMap, nameMap, { path: alias }, parent, record.path)
565
+ })
566
+ } else {
567
+ addRouteRecord(pathMap, nameMap, { path: route.alias }, parent, record.path)
568
+ }
569
+ }
570
+
571
+ if (!pathMap[record.path]) {
572
+ pathMap[record.path] = record
573
+ }
574
+ if (name) {
575
+ if (!nameMap[name]) {
576
+ nameMap[name] = record
577
+ } else if ("development" !== 'production') {
578
+ warn(false, ("Duplicate named routes definition: { name: \"" + name + "\", path: \"" + (record.path) + "\" }"))
579
+ }
580
+ }
581
+ }
582
+
583
+ function normalizePath (path, parent) {
584
+ path = path.replace(/\/$/, '')
585
+ if (path[0] === '/') { return path }
586
+ if (parent == null) { return path }
587
+ return cleanPath(((parent.path) + "/" + path))
588
+ }
589
+
522
590
  var __moduleExports = Array.isArray || function (arr) {
523
591
  return Object.prototype.toString.call(arr) == '[object Array]';
524
592
  };
@@ -957,88 +1025,102 @@ index.tokensToRegExp = tokensToRegExp_1;
957
1025
 
958
1026
  /* */
959
1027
 
960
- function createRouteMap (routes) {
961
- var pathMap = Object.create(null)
962
- var nameMap = Object.create(null)
1028
+ var regexpCache = Object.create(null)
963
1029
 
964
- routes.forEach(function (route) {
965
- addRouteRecord(pathMap, nameMap, route)
966
- })
1030
+ function getRouteRegex (path) {
1031
+ var hit = regexpCache[path]
1032
+ var keys, regexp
967
1033
 
968
- return {
969
- pathMap: pathMap,
970
- nameMap: nameMap
1034
+ if (hit) {
1035
+ keys = hit.keys
1036
+ regexp = hit.regexp
1037
+ } else {
1038
+ keys = []
1039
+ regexp = index(path, keys)
1040
+ regexpCache[path] = { keys: keys, regexp: regexp }
971
1041
  }
1042
+
1043
+ return { keys: keys, regexp: regexp }
972
1044
  }
973
1045
 
974
- function addRouteRecord (
975
- pathMap,
976
- nameMap,
977
- route,
978
- parent,
979
- matchAs
980
- ) {
981
- var path = route.path;
982
- var name = route.name;
983
- assert(path != null, "\"path\" is required in a route configuration.")
1046
+ var regexpCompileCache = Object.create(null)
984
1047
 
985
- var record = {
986
- path: normalizePath(path, parent),
987
- components: route.components || { default: route.component },
988
- instances: {},
989
- name: name,
990
- parent: parent,
991
- matchAs: matchAs,
992
- redirect: route.redirect,
993
- beforeEnter: route.beforeEnter,
994
- meta: route.meta || {}
1048
+ function fillParams (
1049
+ path,
1050
+ params,
1051
+ routeMsg
1052
+ ) {
1053
+ try {
1054
+ var filler =
1055
+ regexpCompileCache[path] ||
1056
+ (regexpCompileCache[path] = index.compile(path))
1057
+ return filler(params || {}, { pretty: true })
1058
+ } catch (e) {
1059
+ if ("development" !== 'production') {
1060
+ warn(false, ("missing param for " + routeMsg + ": " + (e.message)))
1061
+ }
1062
+ return ''
995
1063
  }
1064
+ }
996
1065
 
997
- if (route.children) {
998
- // Warn if route is named and has a default child route.
999
- // If users navigate to this route by name, the default child will
1000
- // not be rendered (GH Issue #629)
1001
- if ("production" !== 'production') {}
1002
- route.children.forEach(function (child) {
1003
- addRouteRecord(pathMap, nameMap, child, record)
1004
- })
1066
+ /* */
1067
+
1068
+ function normalizeLocation (
1069
+ raw,
1070
+ current,
1071
+ append
1072
+ ) {
1073
+ var next = typeof raw === 'string' ? { path: raw } : raw
1074
+ // named target
1075
+ if (next.name || next._normalized) {
1076
+ return next
1005
1077
  }
1006
1078
 
1007
- if (route.alias !== undefined) {
1008
- if (Array.isArray(route.alias)) {
1009
- route.alias.forEach(function (alias) {
1010
- addRouteRecord(pathMap, nameMap, { path: alias }, parent, record.path)
1011
- })
1012
- } else {
1013
- addRouteRecord(pathMap, nameMap, { path: route.alias }, parent, record.path)
1079
+ // relative params
1080
+ if (!next.path && next.params && current) {
1081
+ next = assign({}, next)
1082
+ next._normalized = true
1083
+ var params = assign(assign({}, current.params), next.params)
1084
+ if (current.name) {
1085
+ next.name = current.name
1086
+ next.params = params
1087
+ } else if (current.matched) {
1088
+ var rawPath = current.matched[current.matched.length - 1].path
1089
+ next.path = fillParams(rawPath, params, ("path " + (current.path)))
1090
+ } else if ("development" !== 'production') {
1091
+ warn(false, "relative params navigation requires a current route.")
1014
1092
  }
1093
+ return next
1015
1094
  }
1016
1095
 
1017
- pathMap[record.path] = record
1018
- if (name) {
1019
- if (!nameMap[name]) {
1020
- nameMap[name] = record
1021
- } else {
1022
- warn(false, ("Duplicate named routes definition: { name: \"" + name + "\", path: \"" + (record.path) + "\" }"))
1023
- }
1096
+ var parsedPath = parsePath(next.path || '')
1097
+ var basePath = (current && current.path) || '/'
1098
+ var path = parsedPath.path
1099
+ ? resolvePath(parsedPath.path, basePath, append || next.append)
1100
+ : (current && current.path) || '/'
1101
+ var query = resolveQuery(parsedPath.query, next.query)
1102
+ var hash = next.hash || parsedPath.hash
1103
+ if (hash && hash.charAt(0) !== '#') {
1104
+ hash = "#" + hash
1105
+ }
1106
+
1107
+ return {
1108
+ _normalized: true,
1109
+ path: path,
1110
+ query: query,
1111
+ hash: hash
1024
1112
  }
1025
1113
  }
1026
1114
 
1027
- function normalizePath (path, parent) {
1028
- path = path.replace(/\/$/, '')
1029
- if (path[0] === '/') { return path }
1030
- if (parent == null) { return path }
1031
- return cleanPath(((parent.path) + "/" + path))
1115
+ function assign (a, b) {
1116
+ for (var key in b) {
1117
+ a[key] = b[key]
1118
+ }
1119
+ return a
1032
1120
  }
1033
1121
 
1034
1122
  /* */
1035
1123
 
1036
- var regexpCache = Object.create(null)
1037
-
1038
- var regexpParamsCache = Object.create(null)
1039
-
1040
- var regexpCompileCache = Object.create(null)
1041
-
1042
1124
  function createMatcher (routes) {
1043
1125
  var ref = createRouteMap(routes);
1044
1126
  var pathMap = ref.pathMap;
@@ -1054,7 +1136,9 @@ function createMatcher (routes) {
1054
1136
 
1055
1137
  if (name) {
1056
1138
  var record = nameMap[name]
1057
- var paramNames = getParams(record.path)
1139
+ var paramNames = getRouteRegex(record.path).keys
1140
+ .filter(function (key) { return !key.optional; })
1141
+ .map(function (key) { return key.name; })
1058
1142
 
1059
1143
  if (typeof location.params !== 'object') {
1060
1144
  location.params = {}
@@ -1098,7 +1182,9 @@ function createMatcher (routes) {
1098
1182
  }
1099
1183
 
1100
1184
  if (!redirect || typeof redirect !== 'object') {
1101
- warn(false, ("invalid redirect option: " + (JSON.stringify(redirect))))
1185
+ "development" !== 'production' && warn(
1186
+ false, ("invalid redirect option: " + (JSON.stringify(redirect)))
1187
+ )
1102
1188
  return _createRoute(null, location)
1103
1189
  }
1104
1190
 
@@ -1115,7 +1201,9 @@ function createMatcher (routes) {
1115
1201
  if (name) {
1116
1202
  // resolved named direct
1117
1203
  var targetRecord = nameMap[name]
1118
- assert(targetRecord, ("redirect failed: named route \"" + name + "\" not found."))
1204
+ if ("development" !== 'production') {
1205
+ assert(targetRecord, ("redirect failed: named route \"" + name + "\" not found."))
1206
+ }
1119
1207
  return match({
1120
1208
  _normalized: true,
1121
1209
  name: name,
@@ -1177,22 +1265,6 @@ function createMatcher (routes) {
1177
1265
  return match
1178
1266
  }
1179
1267
 
1180
- function getRouteRegex (path) {
1181
- var hit = regexpCache[path]
1182
- var keys, regexp
1183
-
1184
- if (hit) {
1185
- keys = hit.keys
1186
- regexp = hit.regexp
1187
- } else {
1188
- keys = []
1189
- regexp = index(path, keys)
1190
- regexpCache[path] = { keys: keys, regexp: regexp }
1191
- }
1192
-
1193
- return { keys: keys, regexp: regexp }
1194
- }
1195
-
1196
1268
  function matchRoute (
1197
1269
  path,
1198
1270
  params,
@@ -1218,27 +1290,6 @@ function matchRoute (
1218
1290
  return true
1219
1291
  }
1220
1292
 
1221
- function fillParams (
1222
- path,
1223
- params,
1224
- routeMsg
1225
- ) {
1226
- try {
1227
- var filler =
1228
- regexpCompileCache[path] ||
1229
- (regexpCompileCache[path] = index.compile(path))
1230
- return filler(params || {}, { pretty: true })
1231
- } catch (e) {
1232
- assert(false, ("missing param for " + routeMsg + ": " + (e.message)))
1233
- return ''
1234
- }
1235
- }
1236
-
1237
- function getParams (path) {
1238
- return regexpParamsCache[path] ||
1239
- (regexpParamsCache[path] = getRouteRegex(path).keys.map(function (key) { return key.name; }))
1240
- }
1241
-
1242
1293
  function resolveRecordPath (path, record) {
1243
1294
  return resolvePath(path, record.parent ? record.parent.path : '/', true)
1244
1295
  }
@@ -1296,24 +1347,25 @@ History.prototype.listen = function listen (cb) {
1296
1347
  this.cb = cb
1297
1348
  };
1298
1349
 
1299
- History.prototype.transitionTo = function transitionTo (location, cb) {
1350
+ History.prototype.transitionTo = function transitionTo (location, onComplete, onAbort) {
1300
1351
  var this$1 = this;
1301
1352
 
1302
1353
  var route = this.router.match(location, this.current)
1303
1354
  this.confirmTransition(route, function () {
1304
1355
  this$1.updateRoute(route)
1305
- cb && cb(route)
1356
+ onComplete && onComplete(route)
1306
1357
  this$1.ensureURL()
1307
- })
1358
+ }, onAbort)
1308
1359
  };
1309
1360
 
1310
- History.prototype.confirmTransition = function confirmTransition (route, cb) {
1361
+ History.prototype.confirmTransition = function confirmTransition (route, onComplete, onAbort) {
1311
1362
  var this$1 = this;
1312
1363
 
1313
1364
  var current = this.current
1365
+ var abort = function () { onAbort && onAbort() }
1314
1366
  if (isSameRoute(route, current)) {
1315
1367
  this.ensureURL()
1316
- return
1368
+ return abort()
1317
1369
  }
1318
1370
 
1319
1371
  var ref = resolveQueue(this.current.matched, route.matched);
@@ -1333,14 +1385,18 @@ History.prototype.confirmTransition = function confirmTransition (route, cb) {
1333
1385
 
1334
1386
  this.pending = route
1335
1387
  var iterator = function (hook, next) {
1336
- if (this$1.pending !== route) { return }
1388
+ if (this$1.pending !== route) {
1389
+ return abort()
1390
+ }
1337
1391
  hook(route, current, function (to) {
1338
1392
  if (to === false) {
1339
1393
  // next(false) -> abort navigation, ensure current URL
1340
1394
  this$1.ensureURL(true)
1395
+ abort()
1341
1396
  } else if (typeof to === 'string' || typeof to === 'object') {
1342
1397
  // next('/') or next({ path: '/' }) -> redirect
1343
- this$1.push(to)
1398
+ (typeof to === 'object' && to.replace) ? this$1.replace(to) : this$1.push(to)
1399
+ abort()
1344
1400
  } else {
1345
1401
  // confirm transition and pass on the value
1346
1402
  next(to)
@@ -1356,9 +1412,12 @@ History.prototype.confirmTransition = function confirmTransition (route, cb) {
1356
1412
  // wait until async components are resolved before
1357
1413
  // extracting in-component enter guards
1358
1414
  runQueue(enterGuards, iterator, function () {
1359
- if (this$1.pending === route) {
1360
- this$1.pending = null
1361
- cb(route)
1415
+ if (this$1.pending !== route) {
1416
+ return abort()
1417
+ }
1418
+ this$1.pending = null
1419
+ onComplete(route)
1420
+ if (this$1.router.app) {
1362
1421
  this$1.router.app.$nextTick(function () {
1363
1422
  postEnterCbs.forEach(function (cb) { return cb(); })
1364
1423
  })
@@ -1657,7 +1716,9 @@ var HTML5History = (function (History) {
1657
1716
  if (!behavior) {
1658
1717
  return
1659
1718
  }
1660
- assert(typeof behavior === 'function', "scrollBehavior must be a function")
1719
+ if ("development" !== 'production') {
1720
+ assert(typeof behavior === 'function', "scrollBehavior must be a function")
1721
+ }
1661
1722
 
1662
1723
  // wait until re-render finishes before scrolling
1663
1724
  router.app.$nextTick(function () {
@@ -1722,12 +1783,10 @@ function replaceState (url) {
1722
1783
  var HashHistory = (function (History) {
1723
1784
  function HashHistory (router, base, fallback) {
1724
1785
  History.call(this, router, base)
1725
-
1726
1786
  // check history fallback deeplinking
1727
1787
  if (fallback && this.checkFallback()) {
1728
1788
  return
1729
1789
  }
1730
-
1731
1790
  ensureSlash()
1732
1791
  }
1733
1792
 
@@ -1892,7 +1951,7 @@ var VueRouter = function VueRouter (options) {
1892
1951
  this.history = new AbstractHistory(this)
1893
1952
  break
1894
1953
  default:
1895
- assert(false, ("invalid mode: " + mode))
1954
+ "development" !== 'production' && assert(false, ("invalid mode: " + mode))
1896
1955
  }
1897
1956
  };
1898
1957
 
@@ -1905,7 +1964,7 @@ prototypeAccessors.currentRoute.get = function () {
1905
1964
  VueRouter.prototype.init = function init (app /* Vue component instance */) {
1906
1965
  var this$1 = this;
1907
1966
 
1908
- assert(
1967
+ "development" !== 'production' && assert(
1909
1968
  install.installed,
1910
1969
  "not installed. Make sure to call `Vue.use(VueRouter)` " +
1911
1970
  "before creating root instance."
@@ -1918,11 +1977,12 @@ VueRouter.prototype.init = function init (app /* Vue component instance */) {
1918
1977
  if (history instanceof HTML5History) {
1919
1978
  history.transitionTo(getLocation(history.base))
1920
1979
  } else if (history instanceof HashHistory) {
1921
- history.transitionTo(getHash(), function () {
1980
+ var setupHashListener = function () {
1922
1981
  window.addEventListener('hashchange', function () {
1923
1982
  history.onHashChange()
1924
1983
  })
1925
- })
1984
+ }
1985
+ history.transitionTo(getHash(), setupHashListener, setupHashListener)
1926
1986
  }
1927
1987
 
1928
1988
  history.listen(function (route) {
@@ -1958,19 +2018,44 @@ VueRouter.prototype.forward = function forward () {
1958
2018
  this.go(1)
1959
2019
  };
1960
2020
 
1961
- VueRouter.prototype.getMatchedComponents = function getMatchedComponents () {
1962
- if (!this.currentRoute) {
2021
+ VueRouter.prototype.getMatchedComponents = function getMatchedComponents (to) {
2022
+ var route = to
2023
+ ? this.resolve(to).resolved
2024
+ : this.currentRoute
2025
+ if (!route) {
1963
2026
  return []
1964
2027
  }
1965
- return [].concat.apply([], this.currentRoute.matched.map(function (m) {
2028
+ return [].concat.apply([], route.matched.map(function (m) {
1966
2029
  return Object.keys(m.components).map(function (key) {
1967
2030
  return m.components[key]
1968
2031
  })
1969
2032
  }))
1970
2033
  };
1971
2034
 
2035
+ VueRouter.prototype.resolve = function resolve (
2036
+ to,
2037
+ current,
2038
+ append
2039
+ ) {
2040
+ var normalizedTo = normalizeLocation(to, current || this.history.current, append)
2041
+ var resolved = this.match(normalizedTo, current)
2042
+ var fullPath = resolved.redirectedFrom || resolved.fullPath
2043
+ var base = this.history.base
2044
+ var href = createHref(base, fullPath, this.mode)
2045
+ return {
2046
+ normalizedTo: normalizedTo,
2047
+ resolved: resolved,
2048
+ href: href
2049
+ }
2050
+ };
2051
+
1972
2052
  Object.defineProperties( VueRouter.prototype, prototypeAccessors );
1973
2053
 
2054
+ function createHref (base, fullPath, mode) {
2055
+ var path = mode === 'hash' ? '#' + fullPath : fullPath
2056
+ return base ? cleanPath(base + '/' + path) : path
2057
+ }
2058
+
1974
2059
  VueRouter.install = install
1975
2060
 
1976
2061
  if (inBrowser && window.Vue) {