vuejs 1.0.37 → 1.0.38

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.
@@ -1,14 +1,28 @@
1
1
  /**
2
- * vue-router v2.1.3
2
+ * vue-router v2.2.1
3
3
  * (c) 2017 Evan You
4
4
  * @license MIT
5
5
  */
6
6
  (function (global, factory) {
7
- typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
8
- typeof define === 'function' && define.amd ? define(factory) :
9
- (global.VueRouter = factory());
7
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
8
+ typeof define === 'function' && define.amd ? define(factory) :
9
+ (global.VueRouter = factory());
10
10
  }(this, (function () { 'use strict';
11
11
 
12
+ /* */
13
+
14
+ function assert (condition, message) {
15
+ if (!condition) {
16
+ throw new Error(("[vue-router] " + message))
17
+ }
18
+ }
19
+
20
+ function warn (condition, message) {
21
+ if (!condition) {
22
+ typeof console !== 'undefined' && console.warn(("[vue-router] " + message));
23
+ }
24
+ }
25
+
12
26
  var View = {
13
27
  name: 'router-view',
14
28
  functional: true,
@@ -24,77 +38,91 @@ var View = {
24
38
  var parent = ref.parent;
25
39
  var data = ref.data;
26
40
 
27
- data.routerView = true
41
+ data.routerView = true;
28
42
 
29
- var name = props.name
30
- var route = parent.$route
31
- var cache = parent._routerViewCache || (parent._routerViewCache = {})
43
+ var name = props.name;
44
+ var route = parent.$route;
45
+ var cache = parent._routerViewCache || (parent._routerViewCache = {});
32
46
 
33
47
  // determine current view depth, also check to see if the tree
34
48
  // has been toggled inactive but kept-alive.
35
- var depth = 0
36
- var inactive = false
49
+ var depth = 0;
50
+ var inactive = false;
37
51
  while (parent) {
38
52
  if (parent.$vnode && parent.$vnode.data.routerView) {
39
- depth++
53
+ depth++;
40
54
  }
41
55
  if (parent._inactive) {
42
- inactive = true
56
+ inactive = true;
43
57
  }
44
- parent = parent.$parent
58
+ parent = parent.$parent;
45
59
  }
46
- data.routerViewDepth = depth
60
+ data.routerViewDepth = depth;
47
61
 
48
62
  // render previous view if the tree is inactive and kept-alive
49
63
  if (inactive) {
50
64
  return h(cache[name], data, children)
51
65
  }
52
66
 
53
- var matched = route.matched[depth]
67
+ var matched = route.matched[depth];
54
68
  // render empty node if no matched route
55
69
  if (!matched) {
56
- cache[name] = null
70
+ cache[name] = null;
57
71
  return h()
58
72
  }
59
73
 
60
- var component = cache[name] = matched.components[name]
74
+ var component = cache[name] = matched.components[name];
61
75
 
62
76
  // inject instance registration hooks
63
- var hooks = data.hook || (data.hook = {})
77
+ var hooks = data.hook || (data.hook = {});
64
78
  hooks.init = function (vnode) {
65
- matched.instances[name] = vnode.child
66
- }
79
+ matched.instances[name] = vnode.child;
80
+ };
67
81
  hooks.prepatch = function (oldVnode, vnode) {
68
- matched.instances[name] = vnode.child
69
- }
82
+ matched.instances[name] = vnode.child;
83
+ };
70
84
  hooks.destroy = function (vnode) {
71
85
  if (matched.instances[name] === vnode.child) {
72
- matched.instances[name] = undefined
86
+ matched.instances[name] = undefined;
73
87
  }
74
- }
75
-
76
- return h(component, data, children)
77
- }
78
- }
88
+ };
79
89
 
80
- /* */
90
+ // resolve props
91
+ data.props = resolveProps(route, matched.props && matched.props[name]);
81
92
 
82
- function assert (condition, message) {
83
- if (!condition) {
84
- throw new Error(("[vue-router] " + message))
93
+ return h(component, data, children)
85
94
  }
86
- }
95
+ };
87
96
 
88
- function warn (condition, message) {
89
- if (!condition) {
90
- typeof console !== 'undefined' && console.warn(("[vue-router] " + message))
97
+ function resolveProps (route, config) {
98
+ switch (typeof config) {
99
+ case 'undefined':
100
+ return
101
+ case 'object':
102
+ return config
103
+ case 'function':
104
+ return config(route)
105
+ case 'boolean':
106
+ return config ? route.params : undefined
107
+ default:
108
+ warn(false, ("props in \"" + (route.path) + "\" is a " + (typeof config) + ", expecting an object, function or boolean."));
91
109
  }
92
110
  }
93
111
 
94
112
  /* */
95
113
 
96
- var encode = encodeURIComponent
97
- var decode = decodeURIComponent
114
+ var encodeReserveRE = /[!'()*]/g;
115
+ var encodeReserveReplacer = function (c) { return '%' + c.charCodeAt(0).toString(16); };
116
+ var commaRE = /%2C/g;
117
+
118
+ // fixed encodeURIComponent which is more comformant to RFC3986:
119
+ // - escapes [!'()*]
120
+ // - preserve commas
121
+ var encode = function (str) { return encodeURIComponent(str)
122
+ .replace(encodeReserveRE, encodeReserveReplacer)
123
+ .replace(commaRE, ','); };
124
+
125
+ var decode = decodeURIComponent;
98
126
 
99
127
  function resolveQuery (
100
128
  query,
@@ -103,15 +131,15 @@ function resolveQuery (
103
131
  if ( extraQuery === void 0 ) extraQuery = {};
104
132
 
105
133
  if (query) {
106
- var parsedQuery
134
+ var parsedQuery;
107
135
  try {
108
- parsedQuery = parseQuery(query)
136
+ parsedQuery = parseQuery(query);
109
137
  } catch (e) {
110
- "development" !== 'production' && warn(false, e.message)
111
- parsedQuery = {}
138
+ "development" !== 'production' && warn(false, e.message);
139
+ parsedQuery = {};
112
140
  }
113
141
  for (var key in extraQuery) {
114
- parsedQuery[key] = extraQuery[key]
142
+ parsedQuery[key] = extraQuery[key];
115
143
  }
116
144
  return parsedQuery
117
145
  } else {
@@ -120,36 +148,36 @@ function resolveQuery (
120
148
  }
121
149
 
122
150
  function parseQuery (query) {
123
- var res = {}
151
+ var res = {};
124
152
 
125
- query = query.trim().replace(/^(\?|#|&)/, '')
153
+ query = query.trim().replace(/^(\?|#|&)/, '');
126
154
 
127
155
  if (!query) {
128
156
  return res
129
157
  }
130
158
 
131
159
  query.split('&').forEach(function (param) {
132
- var parts = param.replace(/\+/g, ' ').split('=')
133
- var key = decode(parts.shift())
160
+ var parts = param.replace(/\+/g, ' ').split('=');
161
+ var key = decode(parts.shift());
134
162
  var val = parts.length > 0
135
163
  ? decode(parts.join('='))
136
- : null
164
+ : null;
137
165
 
138
166
  if (res[key] === undefined) {
139
- res[key] = val
167
+ res[key] = val;
140
168
  } else if (Array.isArray(res[key])) {
141
- res[key].push(val)
169
+ res[key].push(val);
142
170
  } else {
143
- res[key] = [res[key], val]
171
+ res[key] = [res[key], val];
144
172
  }
145
- })
173
+ });
146
174
 
147
175
  return res
148
176
  }
149
177
 
150
178
  function stringifyQuery (obj) {
151
179
  var res = obj ? Object.keys(obj).map(function (key) {
152
- var val = obj[key]
180
+ var val = obj[key];
153
181
 
154
182
  if (val === undefined) {
155
183
  return ''
@@ -160,28 +188,28 @@ function stringifyQuery (obj) {
160
188
  }
161
189
 
162
190
  if (Array.isArray(val)) {
163
- var result = []
191
+ var result = [];
164
192
  val.slice().forEach(function (val2) {
165
193
  if (val2 === undefined) {
166
194
  return
167
195
  }
168
196
  if (val2 === null) {
169
- result.push(encode(key))
197
+ result.push(encode(key));
170
198
  } else {
171
- result.push(encode(key) + '=' + encode(val2))
199
+ result.push(encode(key) + '=' + encode(val2));
172
200
  }
173
- })
201
+ });
174
202
  return result.join('&')
175
203
  }
176
204
 
177
205
  return encode(key) + '=' + encode(val)
178
- }).filter(function (x) { return x.length > 0; }).join('&') : null
206
+ }).filter(function (x) { return x.length > 0; }).join('&') : null;
179
207
  return res ? ("?" + res) : ''
180
208
  }
181
209
 
182
210
  /* */
183
211
 
184
- var trailingSlashRE = /\/?$/
212
+ var trailingSlashRE = /\/?$/;
185
213
 
186
214
  function createRoute (
187
215
  record,
@@ -197,9 +225,9 @@ function createRoute (
197
225
  params: location.params || {},
198
226
  fullPath: getFullPath(location),
199
227
  matched: record ? formatMatch(record) : []
200
- }
228
+ };
201
229
  if (redirectedFrom) {
202
- route.redirectedFrom = getFullPath(redirectedFrom)
230
+ route.redirectedFrom = getFullPath(redirectedFrom);
203
231
  }
204
232
  return Object.freeze(route)
205
233
  }
@@ -207,13 +235,13 @@ function createRoute (
207
235
  // the starting route that represents the initial state
208
236
  var START = createRoute(null, {
209
237
  path: '/'
210
- })
238
+ });
211
239
 
212
240
  function formatMatch (record) {
213
- var res = []
241
+ var res = [];
214
242
  while (record) {
215
- res.unshift(record)
216
- record = record.parent
243
+ res.unshift(record);
244
+ record = record.parent;
217
245
  }
218
246
  return res
219
247
  }
@@ -253,8 +281,8 @@ function isObjectEqual (a, b) {
253
281
  if ( a === void 0 ) a = {};
254
282
  if ( b === void 0 ) b = {};
255
283
 
256
- var aKeys = Object.keys(a)
257
- var bKeys = Object.keys(b)
284
+ var aKeys = Object.keys(a);
285
+ var bKeys = Object.keys(b);
258
286
  if (aKeys.length !== bKeys.length) {
259
287
  return false
260
288
  }
@@ -283,7 +311,8 @@ function queryIncludes (current, target) {
283
311
  /* */
284
312
 
285
313
  // work around weird flow bug
286
- var toTypes = [String, Object]
314
+ var toTypes = [String, Object];
315
+ var eventTypes = [String, Array];
287
316
 
288
317
  var Link = {
289
318
  name: 'router-link',
@@ -301,97 +330,95 @@ var Link = {
301
330
  replace: Boolean,
302
331
  activeClass: String,
303
332
  event: {
304
- type: [String, Array],
333
+ type: eventTypes,
305
334
  default: 'click'
306
335
  }
307
336
  },
308
337
  render: function render (h) {
309
338
  var this$1 = this;
310
339
 
311
- var router = this.$router
312
- var current = this.$route
340
+ var router = this.$router;
341
+ var current = this.$route;
313
342
  var ref = router.resolve(this.to, current, this.append);
314
- var normalizedTo = ref.normalizedTo;
315
- var resolved = ref.resolved;
343
+ var location = ref.location;
344
+ var route = ref.route;
316
345
  var href = ref.href;
317
- var classes = {}
318
- var activeClass = this.activeClass || router.options.linkActiveClass || 'router-link-active'
319
- var compareTarget = normalizedTo.path ? createRoute(null, normalizedTo) : resolved
346
+ var classes = {};
347
+ var activeClass = this.activeClass || router.options.linkActiveClass || 'router-link-active';
348
+ var compareTarget = location.path ? createRoute(null, location) : route;
320
349
  classes[activeClass] = this.exact
321
350
  ? isSameRoute(current, compareTarget)
322
- : isIncludedRoute(current, compareTarget)
351
+ : isIncludedRoute(current, compareTarget);
323
352
 
324
353
  var handler = function (e) {
325
354
  if (guardEvent(e)) {
326
355
  if (this$1.replace) {
327
- router.replace(normalizedTo)
356
+ router.replace(location);
328
357
  } else {
329
- router.push(normalizedTo)
358
+ router.push(location);
330
359
  }
331
360
  }
332
- }
361
+ };
333
362
 
334
- var on = { click: guardEvent }
363
+ var on = { click: guardEvent };
335
364
  if (Array.isArray(this.event)) {
336
- this.event.forEach(function (e) { on[e] = handler })
365
+ this.event.forEach(function (e) { on[e] = handler; });
337
366
  } else {
338
- on[this.event] = handler
367
+ on[this.event] = handler;
339
368
  }
340
369
 
341
370
  var data = {
342
371
  class: classes
343
- }
372
+ };
344
373
 
345
374
  if (this.tag === 'a') {
346
- data.on = on
347
- data.attrs = { href: href }
375
+ data.on = on;
376
+ data.attrs = { href: href };
348
377
  } else {
349
378
  // find the first <a> child and apply listener and href
350
- var a = findAnchor(this.$slots.default)
379
+ var a = findAnchor(this.$slots.default);
351
380
  if (a) {
352
381
  // in case the <a> is a static node
353
- a.isStatic = false
354
- var extend = _Vue.util.extend
355
- var aData = a.data = extend({}, a.data)
356
- aData.on = on
357
- var aAttrs = a.data.attrs = extend({}, a.data.attrs)
358
- aAttrs.href = href
382
+ a.isStatic = false;
383
+ var extend = _Vue.util.extend;
384
+ var aData = a.data = extend({}, a.data);
385
+ aData.on = on;
386
+ var aAttrs = a.data.attrs = extend({}, a.data.attrs);
387
+ aAttrs.href = href;
359
388
  } else {
360
389
  // doesn't have <a> child, apply listener to self
361
- data.on = on
390
+ data.on = on;
362
391
  }
363
392
  }
364
393
 
365
394
  return h(this.tag, data, this.$slots.default)
366
395
  }
367
- }
396
+ };
368
397
 
369
398
  function guardEvent (e) {
370
399
  // don't redirect with control keys
371
- /* istanbul ignore if */
372
400
  if (e.metaKey || e.ctrlKey || e.shiftKey) { return }
373
401
  // don't redirect when preventDefault called
374
- /* istanbul ignore if */
375
402
  if (e.defaultPrevented) { return }
376
403
  // don't redirect on right click
377
- /* istanbul ignore if */
378
404
  if (e.button !== undefined && e.button !== 0) { return }
379
405
  // don't redirect if `target="_blank"`
380
- /* istanbul ignore if */
381
406
  if (e.target && e.target.getAttribute) {
382
- var target = e.target.getAttribute('target')
407
+ var target = e.target.getAttribute('target');
383
408
  if (/\b_blank\b/i.test(target)) { return }
384
409
  }
385
-
386
- e.preventDefault()
410
+ // this may be a Weex event which doesn't have this method
411
+ if (e.preventDefault) {
412
+ e.preventDefault();
413
+ }
387
414
  return true
388
415
  }
389
416
 
390
417
  function findAnchor (children) {
391
418
  if (children) {
392
- var child
419
+ var child;
393
420
  for (var i = 0; i < children.length; i++) {
394
- child = children[i]
421
+ child = children[i];
395
422
  if (child.tag === 'a') {
396
423
  return child
397
424
  }
@@ -402,42 +429,46 @@ function findAnchor (children) {
402
429
  }
403
430
  }
404
431
 
405
- var _Vue
432
+ var _Vue;
406
433
 
407
434
  function install (Vue) {
408
435
  if (install.installed) { return }
409
- install.installed = true
436
+ install.installed = true;
410
437
 
411
- _Vue = Vue
438
+ _Vue = Vue;
412
439
 
413
440
  Object.defineProperty(Vue.prototype, '$router', {
414
441
  get: function get () { return this.$root._router }
415
- })
442
+ });
416
443
 
417
444
  Object.defineProperty(Vue.prototype, '$route', {
418
- get: function get$1 () { return this.$root._route }
419
- })
445
+ get: function get () { return this.$root._route }
446
+ });
420
447
 
421
448
  Vue.mixin({
422
449
  beforeCreate: function beforeCreate () {
423
450
  if (this.$options.router) {
424
- this._router = this.$options.router
425
- this._router.init(this)
426
- Vue.util.defineReactive(this, '_route', this._router.history.current)
451
+ this._router = this.$options.router;
452
+ this._router.init(this);
453
+ Vue.util.defineReactive(this, '_route', this._router.history.current);
427
454
  }
428
455
  }
429
- })
456
+ });
430
457
 
431
- Vue.component('router-view', View)
432
- Vue.component('router-link', Link)
458
+ Vue.component('router-view', View);
459
+ Vue.component('router-link', Link);
433
460
 
434
- var strats = Vue.config.optionMergeStrategies
461
+ var strats = Vue.config.optionMergeStrategies;
435
462
  // use the same hook merging strategy for route hooks
436
- strats.beforeRouteEnter = strats.beforeRouteLeave = strats.created
463
+ strats.beforeRouteEnter = strats.beforeRouteLeave = strats.created;
437
464
  }
438
465
 
439
466
  /* */
440
467
 
468
+ var inBrowser = typeof window !== 'undefined';
469
+
470
+ /* */
471
+
441
472
  function resolvePath (
442
473
  relative,
443
474
  base,
@@ -451,50 +482,50 @@ function resolvePath (
451
482
  return base + relative
452
483
  }
453
484
 
454
- var stack = base.split('/')
485
+ var stack = base.split('/');
455
486
 
456
487
  // remove trailing segment if:
457
488
  // - not appending
458
489
  // - appending to trailing slash (last segment is empty)
459
490
  if (!append || !stack[stack.length - 1]) {
460
- stack.pop()
491
+ stack.pop();
461
492
  }
462
493
 
463
494
  // resolve relative path
464
- var segments = relative.replace(/^\//, '').split('/')
495
+ var segments = relative.replace(/^\//, '').split('/');
465
496
  for (var i = 0; i < segments.length; i++) {
466
- var segment = segments[i]
497
+ var segment = segments[i];
467
498
  if (segment === '.') {
468
499
  continue
469
500
  } else if (segment === '..') {
470
- stack.pop()
501
+ stack.pop();
471
502
  } else {
472
- stack.push(segment)
503
+ stack.push(segment);
473
504
  }
474
505
  }
475
506
 
476
507
  // ensure leading slash
477
508
  if (stack[0] !== '') {
478
- stack.unshift('')
509
+ stack.unshift('');
479
510
  }
480
511
 
481
512
  return stack.join('/')
482
513
  }
483
514
 
484
515
  function parsePath (path) {
485
- var hash = ''
486
- var query = ''
516
+ var hash = '';
517
+ var query = '';
487
518
 
488
- var hashIndex = path.indexOf('#')
519
+ var hashIndex = path.indexOf('#');
489
520
  if (hashIndex >= 0) {
490
- hash = path.slice(hashIndex)
491
- path = path.slice(0, hashIndex)
521
+ hash = path.slice(hashIndex);
522
+ path = path.slice(0, hashIndex);
492
523
  }
493
524
 
494
- var queryIndex = path.indexOf('?')
525
+ var queryIndex = path.indexOf('?');
495
526
  if (queryIndex >= 0) {
496
- query = path.slice(queryIndex + 1)
497
- path = path.slice(0, queryIndex)
527
+ query = path.slice(queryIndex + 1);
528
+ path = path.slice(0, queryIndex);
498
529
  }
499
530
 
500
531
  return {
@@ -510,13 +541,17 @@ function cleanPath (path) {
510
541
 
511
542
  /* */
512
543
 
513
- function createRouteMap (routes) {
514
- var pathMap = Object.create(null)
515
- var nameMap = Object.create(null)
544
+ function createRouteMap (
545
+ routes,
546
+ oldPathMap,
547
+ oldNameMap
548
+ ) {
549
+ var pathMap = oldPathMap || Object.create(null);
550
+ var nameMap = oldNameMap || Object.create(null);
516
551
 
517
552
  routes.forEach(function (route) {
518
- addRouteRecord(pathMap, nameMap, route)
519
- })
553
+ addRouteRecord(pathMap, nameMap, route);
554
+ });
520
555
 
521
556
  return {
522
557
  pathMap: pathMap,
@@ -533,13 +568,13 @@ function addRouteRecord (
533
568
  ) {
534
569
  var path = route.path;
535
570
  var name = route.name;
536
- if ("development" !== 'production') {
537
- assert(path != null, "\"path\" is required in a route configuration.")
571
+ {
572
+ assert(path != null, "\"path\" is required in a route configuration.");
538
573
  assert(
539
574
  typeof route.component !== 'string',
540
575
  "route config \"component\" for path: " + (String(path || name)) + " cannot be a " +
541
576
  "string id. Use an actual component instead."
542
- )
577
+ );
543
578
  }
544
579
 
545
580
  var record = {
@@ -551,14 +586,19 @@ function addRouteRecord (
551
586
  matchAs: matchAs,
552
587
  redirect: route.redirect,
553
588
  beforeEnter: route.beforeEnter,
554
- meta: route.meta || {}
555
- }
589
+ meta: route.meta || {},
590
+ props: route.props == null
591
+ ? {}
592
+ : route.components
593
+ ? route.props
594
+ : { default: route.props }
595
+ };
556
596
 
557
597
  if (route.children) {
558
598
  // Warn if route is named and has a default child route.
559
599
  // If users navigate to this route by name, the default child will
560
600
  // not be rendered (GH Issue #629)
561
- if ("development" !== 'production') {
601
+ {
562
602
  if (route.name && route.children.some(function (child) { return /^\/?$/.test(child.path); })) {
563
603
  warn(
564
604
  false,
@@ -567,15 +607,15 @@ function addRouteRecord (
567
607
  "the default child route will not be rendered. Remove the name from " +
568
608
  "this route and use the name of the default child route for named " +
569
609
  "links instead."
570
- )
610
+ );
571
611
  }
572
612
  }
573
613
  route.children.forEach(function (child) {
574
614
  var childMatchAs = matchAs
575
615
  ? cleanPath((matchAs + "/" + (child.path)))
576
- : undefined
577
- addRouteRecord(pathMap, nameMap, child, record, childMatchAs)
578
- })
616
+ : undefined;
617
+ addRouteRecord(pathMap, nameMap, child, record, childMatchAs);
618
+ });
579
619
  }
580
620
 
581
621
  if (route.alias !== undefined) {
@@ -584,56 +624,56 @@ function addRouteRecord (
584
624
  var aliasRoute = {
585
625
  path: alias,
586
626
  children: route.children
587
- }
588
- addRouteRecord(pathMap, nameMap, aliasRoute, parent, record.path)
589
- })
627
+ };
628
+ addRouteRecord(pathMap, nameMap, aliasRoute, parent, record.path);
629
+ });
590
630
  } else {
591
631
  var aliasRoute = {
592
632
  path: route.alias,
593
633
  children: route.children
594
- }
595
- addRouteRecord(pathMap, nameMap, aliasRoute, parent, record.path)
634
+ };
635
+ addRouteRecord(pathMap, nameMap, aliasRoute, parent, record.path);
596
636
  }
597
637
  }
598
638
 
599
639
  if (!pathMap[record.path]) {
600
- pathMap[record.path] = record
640
+ pathMap[record.path] = record;
601
641
  }
602
642
 
603
643
  if (name) {
604
644
  if (!nameMap[name]) {
605
- nameMap[name] = record
606
- } else if ("development" !== 'production') {
645
+ nameMap[name] = record;
646
+ } else if ("development" !== 'production' && !matchAs) {
607
647
  warn(
608
648
  false,
609
649
  "Duplicate named routes definition: " +
610
650
  "{ name: \"" + name + "\", path: \"" + (record.path) + "\" }"
611
- )
651
+ );
612
652
  }
613
653
  }
614
654
  }
615
655
 
616
656
  function normalizePath (path, parent) {
617
- path = path.replace(/\/$/, '')
657
+ path = path.replace(/\/$/, '');
618
658
  if (path[0] === '/') { return path }
619
659
  if (parent == null) { return path }
620
660
  return cleanPath(((parent.path) + "/" + path))
621
661
  }
622
662
 
623
- var __moduleExports = Array.isArray || function (arr) {
663
+ var index$1 = Array.isArray || function (arr) {
624
664
  return Object.prototype.toString.call(arr) == '[object Array]';
625
665
  };
626
666
 
627
- var isarray = __moduleExports
667
+ var isarray = index$1;
628
668
 
629
669
  /**
630
670
  * Expose `pathToRegexp`.
631
671
  */
632
- var index = pathToRegexp
633
- var parse_1 = parse
634
- var compile_1 = compile
635
- var tokensToFunction_1 = tokensToFunction
636
- var tokensToRegExp_1 = tokensToRegExp
672
+ var index = pathToRegexp;
673
+ var parse_1 = parse;
674
+ var compile_1 = compile;
675
+ var tokensToFunction_1 = tokensToFunction;
676
+ var tokensToRegExp_1 = tokensToRegExp;
637
677
 
638
678
  /**
639
679
  * The main path matching regexp utility.
@@ -651,7 +691,7 @@ var PATH_REGEXP = new RegExp([
651
691
  // "/route(\\d+)" => [undefined, undefined, undefined, "\d+", undefined, undefined]
652
692
  // "/*" => ["/", undefined, undefined, undefined, undefined, "*"]
653
693
  '([\\/.])?(?:(?:\\:(\\w+)(?:\\(((?:\\\\.|[^\\\\()])+)\\))?|\\(((?:\\\\.|[^\\\\()])+)\\))([+*?])?|(\\*))'
654
- ].join('|'), 'g')
694
+ ].join('|'), 'g');
655
695
 
656
696
  /**
657
697
  * Parse a string for the raw tokens.
@@ -661,45 +701,45 @@ var PATH_REGEXP = new RegExp([
661
701
  * @return {!Array}
662
702
  */
663
703
  function parse (str, options) {
664
- var tokens = []
665
- var key = 0
666
- var index = 0
667
- var path = ''
668
- var defaultDelimiter = options && options.delimiter || '/'
669
- var res
704
+ var tokens = [];
705
+ var key = 0;
706
+ var index = 0;
707
+ var path = '';
708
+ var defaultDelimiter = options && options.delimiter || '/';
709
+ var res;
670
710
 
671
711
  while ((res = PATH_REGEXP.exec(str)) != null) {
672
- var m = res[0]
673
- var escaped = res[1]
674
- var offset = res.index
675
- path += str.slice(index, offset)
676
- index = offset + m.length
712
+ var m = res[0];
713
+ var escaped = res[1];
714
+ var offset = res.index;
715
+ path += str.slice(index, offset);
716
+ index = offset + m.length;
677
717
 
678
718
  // Ignore already escaped sequences.
679
719
  if (escaped) {
680
- path += escaped[1]
720
+ path += escaped[1];
681
721
  continue
682
722
  }
683
723
 
684
- var next = str[index]
685
- var prefix = res[2]
686
- var name = res[3]
687
- var capture = res[4]
688
- var group = res[5]
689
- var modifier = res[6]
690
- var asterisk = res[7]
724
+ var next = str[index];
725
+ var prefix = res[2];
726
+ var name = res[3];
727
+ var capture = res[4];
728
+ var group = res[5];
729
+ var modifier = res[6];
730
+ var asterisk = res[7];
691
731
 
692
732
  // Push the current path onto the tokens.
693
733
  if (path) {
694
- tokens.push(path)
695
- path = ''
734
+ tokens.push(path);
735
+ path = '';
696
736
  }
697
737
 
698
- var partial = prefix != null && next != null && next !== prefix
699
- var repeat = modifier === '+' || modifier === '*'
700
- var optional = modifier === '?' || modifier === '*'
701
- var delimiter = res[2] || defaultDelimiter
702
- var pattern = capture || group
738
+ var partial = prefix != null && next != null && next !== prefix;
739
+ var repeat = modifier === '+' || modifier === '*';
740
+ var optional = modifier === '?' || modifier === '*';
741
+ var delimiter = res[2] || defaultDelimiter;
742
+ var pattern = capture || group;
703
743
 
704
744
  tokens.push({
705
745
  name: name || key++,
@@ -710,17 +750,17 @@ function parse (str, options) {
710
750
  partial: partial,
711
751
  asterisk: !!asterisk,
712
752
  pattern: pattern ? escapeGroup(pattern) : (asterisk ? '.*' : '[^' + escapeString(delimiter) + ']+?')
713
- })
753
+ });
714
754
  }
715
755
 
716
756
  // Match any characters still remaining.
717
757
  if (index < str.length) {
718
- path += str.substr(index)
758
+ path += str.substr(index);
719
759
  }
720
760
 
721
761
  // If the path exists, push it onto the end.
722
762
  if (path) {
723
- tokens.push(path)
763
+ tokens.push(path);
724
764
  }
725
765
 
726
766
  return tokens
@@ -766,38 +806,38 @@ function encodeAsterisk (str) {
766
806
  */
767
807
  function tokensToFunction (tokens) {
768
808
  // Compile all the tokens into regexps.
769
- var matches = new Array(tokens.length)
809
+ var matches = new Array(tokens.length);
770
810
 
771
811
  // Compile all the patterns before compilation.
772
812
  for (var i = 0; i < tokens.length; i++) {
773
813
  if (typeof tokens[i] === 'object') {
774
- matches[i] = new RegExp('^(?:' + tokens[i].pattern + ')$')
814
+ matches[i] = new RegExp('^(?:' + tokens[i].pattern + ')$');
775
815
  }
776
816
  }
777
817
 
778
818
  return function (obj, opts) {
779
- var path = ''
780
- var data = obj || {}
781
- var options = opts || {}
782
- var encode = options.pretty ? encodeURIComponentPretty : encodeURIComponent
819
+ var path = '';
820
+ var data = obj || {};
821
+ var options = opts || {};
822
+ var encode = options.pretty ? encodeURIComponentPretty : encodeURIComponent;
783
823
 
784
824
  for (var i = 0; i < tokens.length; i++) {
785
- var token = tokens[i]
825
+ var token = tokens[i];
786
826
 
787
827
  if (typeof token === 'string') {
788
- path += token
828
+ path += token;
789
829
 
790
830
  continue
791
831
  }
792
832
 
793
- var value = data[token.name]
794
- var segment
833
+ var value = data[token.name];
834
+ var segment;
795
835
 
796
836
  if (value == null) {
797
837
  if (token.optional) {
798
838
  // Prepend partial segment prefixes.
799
839
  if (token.partial) {
800
- path += token.prefix
840
+ path += token.prefix;
801
841
  }
802
842
 
803
843
  continue
@@ -820,25 +860,25 @@ function tokensToFunction (tokens) {
820
860
  }
821
861
 
822
862
  for (var j = 0; j < value.length; j++) {
823
- segment = encode(value[j])
863
+ segment = encode(value[j]);
824
864
 
825
865
  if (!matches[i].test(segment)) {
826
866
  throw new TypeError('Expected all "' + token.name + '" to match "' + token.pattern + '", but received `' + JSON.stringify(segment) + '`')
827
867
  }
828
868
 
829
- path += (j === 0 ? token.prefix : token.delimiter) + segment
869
+ path += (j === 0 ? token.prefix : token.delimiter) + segment;
830
870
  }
831
871
 
832
872
  continue
833
873
  }
834
874
 
835
- segment = token.asterisk ? encodeAsterisk(value) : encode(value)
875
+ segment = token.asterisk ? encodeAsterisk(value) : encode(value);
836
876
 
837
877
  if (!matches[i].test(segment)) {
838
878
  throw new TypeError('Expected "' + token.name + '" to match "' + token.pattern + '", but received "' + segment + '"')
839
879
  }
840
880
 
841
- path += token.prefix + segment
881
+ path += token.prefix + segment;
842
882
  }
843
883
 
844
884
  return path
@@ -873,7 +913,7 @@ function escapeGroup (group) {
873
913
  * @return {!RegExp}
874
914
  */
875
915
  function attachKeys (re, keys) {
876
- re.keys = keys
916
+ re.keys = keys;
877
917
  return re
878
918
  }
879
919
 
@@ -896,7 +936,7 @@ function flags (options) {
896
936
  */
897
937
  function regexpToRegexp (path, keys) {
898
938
  // Use a negative lookahead to match only capturing groups.
899
- var groups = path.source.match(/\((?!\?)/g)
939
+ var groups = path.source.match(/\((?!\?)/g);
900
940
 
901
941
  if (groups) {
902
942
  for (var i = 0; i < groups.length; i++) {
@@ -909,7 +949,7 @@ function regexpToRegexp (path, keys) {
909
949
  partial: false,
910
950
  asterisk: false,
911
951
  pattern: null
912
- })
952
+ });
913
953
  }
914
954
  }
915
955
 
@@ -925,13 +965,13 @@ function regexpToRegexp (path, keys) {
925
965
  * @return {!RegExp}
926
966
  */
927
967
  function arrayToRegexp (path, keys, options) {
928
- var parts = []
968
+ var parts = [];
929
969
 
930
970
  for (var i = 0; i < path.length; i++) {
931
- parts.push(pathToRegexp(path[i], keys, options).source)
971
+ parts.push(pathToRegexp(path[i], keys, options).source);
932
972
  }
933
973
 
934
- var regexp = new RegExp('(?:' + parts.join('|') + ')', flags(options))
974
+ var regexp = new RegExp('(?:' + parts.join('|') + ')', flags(options));
935
975
 
936
976
  return attachKeys(regexp, keys)
937
977
  }
@@ -958,63 +998,63 @@ function stringToRegexp (path, keys, options) {
958
998
  */
959
999
  function tokensToRegExp (tokens, keys, options) {
960
1000
  if (!isarray(keys)) {
961
- options = /** @type {!Object} */ (keys || options)
962
- keys = []
1001
+ options = /** @type {!Object} */ (keys || options);
1002
+ keys = [];
963
1003
  }
964
1004
 
965
- options = options || {}
1005
+ options = options || {};
966
1006
 
967
- var strict = options.strict
968
- var end = options.end !== false
969
- var route = ''
1007
+ var strict = options.strict;
1008
+ var end = options.end !== false;
1009
+ var route = '';
970
1010
 
971
1011
  // Iterate over the tokens and create our regexp string.
972
1012
  for (var i = 0; i < tokens.length; i++) {
973
- var token = tokens[i]
1013
+ var token = tokens[i];
974
1014
 
975
1015
  if (typeof token === 'string') {
976
- route += escapeString(token)
1016
+ route += escapeString(token);
977
1017
  } else {
978
- var prefix = escapeString(token.prefix)
979
- var capture = '(?:' + token.pattern + ')'
1018
+ var prefix = escapeString(token.prefix);
1019
+ var capture = '(?:' + token.pattern + ')';
980
1020
 
981
- keys.push(token)
1021
+ keys.push(token);
982
1022
 
983
1023
  if (token.repeat) {
984
- capture += '(?:' + prefix + capture + ')*'
1024
+ capture += '(?:' + prefix + capture + ')*';
985
1025
  }
986
1026
 
987
1027
  if (token.optional) {
988
1028
  if (!token.partial) {
989
- capture = '(?:' + prefix + '(' + capture + '))?'
1029
+ capture = '(?:' + prefix + '(' + capture + '))?';
990
1030
  } else {
991
- capture = prefix + '(' + capture + ')?'
1031
+ capture = prefix + '(' + capture + ')?';
992
1032
  }
993
1033
  } else {
994
- capture = prefix + '(' + capture + ')'
1034
+ capture = prefix + '(' + capture + ')';
995
1035
  }
996
1036
 
997
- route += capture
1037
+ route += capture;
998
1038
  }
999
1039
  }
1000
1040
 
1001
- var delimiter = escapeString(options.delimiter || '/')
1002
- var endsWithDelimiter = route.slice(-delimiter.length) === delimiter
1041
+ var delimiter = escapeString(options.delimiter || '/');
1042
+ var endsWithDelimiter = route.slice(-delimiter.length) === delimiter;
1003
1043
 
1004
1044
  // In non-strict mode we allow a slash at the end of match. If the path to
1005
1045
  // match already ends with a slash, we remove it for consistency. The slash
1006
1046
  // is valid at the end of a path match, not in the middle. This is important
1007
1047
  // in non-ending mode, where "/test/" shouldn't match "/test//route".
1008
1048
  if (!strict) {
1009
- route = (endsWithDelimiter ? route.slice(0, -delimiter.length) : route) + '(?:' + delimiter + '(?=$))?'
1049
+ route = (endsWithDelimiter ? route.slice(0, -delimiter.length) : route) + '(?:' + delimiter + '(?=$))?';
1010
1050
  }
1011
1051
 
1012
1052
  if (end) {
1013
- route += '$'
1053
+ route += '$';
1014
1054
  } else {
1015
1055
  // In non-ending mode, we need the capturing groups to match as much as
1016
1056
  // possible by using a positive lookahead to the end or next path segment.
1017
- route += strict && endsWithDelimiter ? '' : '(?=' + delimiter + '|$)'
1057
+ route += strict && endsWithDelimiter ? '' : '(?=' + delimiter + '|$)';
1018
1058
  }
1019
1059
 
1020
1060
  return attachKeys(new RegExp('^' + route, flags(options)), keys)
@@ -1034,11 +1074,11 @@ function tokensToRegExp (tokens, keys, options) {
1034
1074
  */
1035
1075
  function pathToRegexp (path, keys, options) {
1036
1076
  if (!isarray(keys)) {
1037
- options = /** @type {!Object} */ (keys || options)
1038
- keys = []
1077
+ options = /** @type {!Object} */ (keys || options);
1078
+ keys = [];
1039
1079
  }
1040
1080
 
1041
- options = options || {}
1081
+ options = options || {};
1042
1082
 
1043
1083
  if (path instanceof RegExp) {
1044
1084
  return regexpToRegexp(path, /** @type {!Array} */ (keys))
@@ -1058,25 +1098,25 @@ index.tokensToRegExp = tokensToRegExp_1;
1058
1098
 
1059
1099
  /* */
1060
1100
 
1061
- var regexpCache = Object.create(null)
1101
+ var regexpCache = Object.create(null);
1062
1102
 
1063
1103
  function getRouteRegex (path) {
1064
- var hit = regexpCache[path]
1065
- var keys, regexp
1104
+ var hit = regexpCache[path];
1105
+ var keys, regexp;
1066
1106
 
1067
1107
  if (hit) {
1068
- keys = hit.keys
1069
- regexp = hit.regexp
1108
+ keys = hit.keys;
1109
+ regexp = hit.regexp;
1070
1110
  } else {
1071
- keys = []
1072
- regexp = index(path, keys)
1073
- regexpCache[path] = { keys: keys, regexp: regexp }
1111
+ keys = [];
1112
+ regexp = index(path, keys);
1113
+ regexpCache[path] = { keys: keys, regexp: regexp };
1074
1114
  }
1075
1115
 
1076
1116
  return { keys: keys, regexp: regexp }
1077
1117
  }
1078
1118
 
1079
- var regexpCompileCache = Object.create(null)
1119
+ var regexpCompileCache = Object.create(null);
1080
1120
 
1081
1121
  function fillParams (
1082
1122
  path,
@@ -1086,11 +1126,11 @@ function fillParams (
1086
1126
  try {
1087
1127
  var filler =
1088
1128
  regexpCompileCache[path] ||
1089
- (regexpCompileCache[path] = index.compile(path))
1129
+ (regexpCompileCache[path] = index.compile(path));
1090
1130
  return filler(params || {}, { pretty: true })
1091
1131
  } catch (e) {
1092
- if ("development" !== 'production') {
1093
- warn(false, ("missing param for " + routeMsg + ": " + (e.message)))
1132
+ {
1133
+ warn(false, ("missing param for " + routeMsg + ": " + (e.message)));
1094
1134
  }
1095
1135
  return ''
1096
1136
  }
@@ -1103,7 +1143,7 @@ function normalizeLocation (
1103
1143
  current,
1104
1144
  append
1105
1145
  ) {
1106
- var next = typeof raw === 'string' ? { path: raw } : raw
1146
+ var next = typeof raw === 'string' ? { path: raw } : raw;
1107
1147
  // named target
1108
1148
  if (next.name || next._normalized) {
1109
1149
  return next
@@ -1111,30 +1151,30 @@ function normalizeLocation (
1111
1151
 
1112
1152
  // relative params
1113
1153
  if (!next.path && next.params && current) {
1114
- next = assign({}, next)
1115
- next._normalized = true
1116
- var params = assign(assign({}, current.params), next.params)
1154
+ next = assign({}, next);
1155
+ next._normalized = true;
1156
+ var params = assign(assign({}, current.params), next.params);
1117
1157
  if (current.name) {
1118
- next.name = current.name
1119
- next.params = params
1158
+ next.name = current.name;
1159
+ next.params = params;
1120
1160
  } else if (current.matched) {
1121
- var rawPath = current.matched[current.matched.length - 1].path
1122
- next.path = fillParams(rawPath, params, ("path " + (current.path)))
1123
- } else if ("development" !== 'production') {
1124
- warn(false, "relative params navigation requires a current route.")
1161
+ var rawPath = current.matched[current.matched.length - 1].path;
1162
+ next.path = fillParams(rawPath, params, ("path " + (current.path)));
1163
+ } else {
1164
+ warn(false, "relative params navigation requires a current route.");
1125
1165
  }
1126
1166
  return next
1127
1167
  }
1128
1168
 
1129
- var parsedPath = parsePath(next.path || '')
1130
- var basePath = (current && current.path) || '/'
1169
+ var parsedPath = parsePath(next.path || '');
1170
+ var basePath = (current && current.path) || '/';
1131
1171
  var path = parsedPath.path
1132
1172
  ? resolvePath(parsedPath.path, basePath, append || next.append)
1133
- : (current && current.path) || '/'
1134
- var query = resolveQuery(parsedPath.query, next.query)
1135
- var hash = next.hash || parsedPath.hash
1173
+ : (current && current.path) || '/';
1174
+ var query = resolveQuery(parsedPath.query, next.query);
1175
+ var hash = next.hash || parsedPath.hash;
1136
1176
  if (hash && hash.charAt(0) !== '#') {
1137
- hash = "#" + hash
1177
+ hash = "#" + hash;
1138
1178
  }
1139
1179
 
1140
1180
  return {
@@ -1147,7 +1187,7 @@ function normalizeLocation (
1147
1187
 
1148
1188
  function assign (a, b) {
1149
1189
  for (var key in b) {
1150
- a[key] = b[key]
1190
+ a[key] = b[key];
1151
1191
  }
1152
1192
  return a
1153
1193
  }
@@ -1159,41 +1199,45 @@ function createMatcher (routes) {
1159
1199
  var pathMap = ref.pathMap;
1160
1200
  var nameMap = ref.nameMap;
1161
1201
 
1202
+ function addRoutes (routes) {
1203
+ createRouteMap(routes, pathMap, nameMap);
1204
+ }
1205
+
1162
1206
  function match (
1163
1207
  raw,
1164
1208
  currentRoute,
1165
1209
  redirectedFrom
1166
1210
  ) {
1167
- var location = normalizeLocation(raw, currentRoute)
1211
+ var location = normalizeLocation(raw, currentRoute);
1168
1212
  var name = location.name;
1169
1213
 
1170
1214
  if (name) {
1171
- var record = nameMap[name]
1172
- if ("development" !== 'production') {
1173
- warn(record, ("Route with name '" + name + "' does not exist"))
1215
+ var record = nameMap[name];
1216
+ {
1217
+ warn(record, ("Route with name '" + name + "' does not exist"));
1174
1218
  }
1175
1219
  var paramNames = getRouteRegex(record.path).keys
1176
1220
  .filter(function (key) { return !key.optional; })
1177
- .map(function (key) { return key.name; })
1221
+ .map(function (key) { return key.name; });
1178
1222
 
1179
1223
  if (typeof location.params !== 'object') {
1180
- location.params = {}
1224
+ location.params = {};
1181
1225
  }
1182
1226
 
1183
1227
  if (currentRoute && typeof currentRoute.params === 'object') {
1184
1228
  for (var key in currentRoute.params) {
1185
1229
  if (!(key in location.params) && paramNames.indexOf(key) > -1) {
1186
- location.params[key] = currentRoute.params[key]
1230
+ location.params[key] = currentRoute.params[key];
1187
1231
  }
1188
1232
  }
1189
1233
  }
1190
1234
 
1191
1235
  if (record) {
1192
- location.path = fillParams(record.path, location.params, ("named route \"" + name + "\""))
1236
+ location.path = fillParams(record.path, location.params, ("named route \"" + name + "\""));
1193
1237
  return _createRoute(record, location, redirectedFrom)
1194
1238
  }
1195
1239
  } else if (location.path) {
1196
- location.params = {}
1240
+ location.params = {};
1197
1241
  for (var path in pathMap) {
1198
1242
  if (matchRoute(path, location.params, location.path)) {
1199
1243
  return _createRoute(pathMap[path], location, redirectedFrom)
@@ -1208,37 +1252,37 @@ function createMatcher (routes) {
1208
1252
  record,
1209
1253
  location
1210
1254
  ) {
1211
- var originalRedirect = record.redirect
1255
+ var originalRedirect = record.redirect;
1212
1256
  var redirect = typeof originalRedirect === 'function'
1213
1257
  ? originalRedirect(createRoute(record, location))
1214
- : originalRedirect
1258
+ : originalRedirect;
1215
1259
 
1216
1260
  if (typeof redirect === 'string') {
1217
- redirect = { path: redirect }
1261
+ redirect = { path: redirect };
1218
1262
  }
1219
1263
 
1220
1264
  if (!redirect || typeof redirect !== 'object') {
1221
1265
  "development" !== 'production' && warn(
1222
1266
  false, ("invalid redirect option: " + (JSON.stringify(redirect)))
1223
- )
1267
+ );
1224
1268
  return _createRoute(null, location)
1225
1269
  }
1226
1270
 
1227
- var re = redirect
1271
+ var re = redirect;
1228
1272
  var name = re.name;
1229
1273
  var path = re.path;
1230
1274
  var query = location.query;
1231
1275
  var hash = location.hash;
1232
1276
  var params = location.params;
1233
- query = re.hasOwnProperty('query') ? re.query : query
1234
- hash = re.hasOwnProperty('hash') ? re.hash : hash
1235
- params = re.hasOwnProperty('params') ? re.params : params
1277
+ query = re.hasOwnProperty('query') ? re.query : query;
1278
+ hash = re.hasOwnProperty('hash') ? re.hash : hash;
1279
+ params = re.hasOwnProperty('params') ? re.params : params;
1236
1280
 
1237
1281
  if (name) {
1238
1282
  // resolved named direct
1239
- var targetRecord = nameMap[name]
1240
- if ("development" !== 'production') {
1241
- assert(targetRecord, ("redirect failed: named route \"" + name + "\" not found."))
1283
+ var targetRecord = nameMap[name];
1284
+ {
1285
+ assert(targetRecord, ("redirect failed: named route \"" + name + "\" not found."));
1242
1286
  }
1243
1287
  return match({
1244
1288
  _normalized: true,
@@ -1249,9 +1293,9 @@ function createMatcher (routes) {
1249
1293
  }, undefined, location)
1250
1294
  } else if (path) {
1251
1295
  // 1. resolve relative redirect
1252
- var rawPath = resolveRecordPath(path, record)
1296
+ var rawPath = resolveRecordPath(path, record);
1253
1297
  // 2. resolve params
1254
- var resolvedPath = fillParams(rawPath, params, ("redirect route with path \"" + rawPath + "\""))
1298
+ var resolvedPath = fillParams(rawPath, params, ("redirect route with path \"" + rawPath + "\""));
1255
1299
  // 3. rematch with existing query and hash
1256
1300
  return match({
1257
1301
  _normalized: true,
@@ -1260,7 +1304,7 @@ function createMatcher (routes) {
1260
1304
  hash: hash
1261
1305
  }, undefined, location)
1262
1306
  } else {
1263
- warn(false, ("invalid redirect option: " + (JSON.stringify(redirect))))
1307
+ warn(false, ("invalid redirect option: " + (JSON.stringify(redirect))));
1264
1308
  return _createRoute(null, location)
1265
1309
  }
1266
1310
  }
@@ -1270,15 +1314,15 @@ function createMatcher (routes) {
1270
1314
  location,
1271
1315
  matchAs
1272
1316
  ) {
1273
- var aliasedPath = fillParams(matchAs, location.params, ("aliased route with path \"" + matchAs + "\""))
1317
+ var aliasedPath = fillParams(matchAs, location.params, ("aliased route with path \"" + matchAs + "\""));
1274
1318
  var aliasedMatch = match({
1275
1319
  _normalized: true,
1276
1320
  path: aliasedPath
1277
- })
1321
+ });
1278
1322
  if (aliasedMatch) {
1279
- var matched = aliasedMatch.matched
1280
- var aliasedRecord = matched[matched.length - 1]
1281
- location.params = aliasedMatch.params
1323
+ var matched = aliasedMatch.matched;
1324
+ var aliasedRecord = matched[matched.length - 1];
1325
+ location.params = aliasedMatch.params;
1282
1326
  return _createRoute(aliasedRecord, location)
1283
1327
  }
1284
1328
  return _createRoute(null, location)
@@ -1298,7 +1342,10 @@ function createMatcher (routes) {
1298
1342
  return createRoute(record, location, redirectedFrom)
1299
1343
  }
1300
1344
 
1301
- return match
1345
+ return {
1346
+ match: match,
1347
+ addRoutes: addRoutes
1348
+ }
1302
1349
  }
1303
1350
 
1304
1351
  function matchRoute (
@@ -1309,7 +1356,7 @@ function matchRoute (
1309
1356
  var ref = getRouteRegex(path);
1310
1357
  var regexp = ref.regexp;
1311
1358
  var keys = ref.keys;
1312
- var m = pathname.match(regexp)
1359
+ var m = pathname.match(regexp);
1313
1360
 
1314
1361
  if (!m) {
1315
1362
  return false
@@ -1318,9 +1365,9 @@ function matchRoute (
1318
1365
  }
1319
1366
 
1320
1367
  for (var i = 1, len = m.length; i < len; ++i) {
1321
- var key = keys[i - 1]
1322
- var val = typeof m[i] === 'string' ? decodeURIComponent(m[i]) : m[i]
1323
- if (key) { params[key.name] = val }
1368
+ var key = keys[i - 1];
1369
+ var val = typeof m[i] === 'string' ? decodeURIComponent(m[i]) : m[i];
1370
+ if (key) { params[key.name] = val; }
1324
1371
  }
1325
1372
 
1326
1373
  return true
@@ -1332,10 +1379,107 @@ function resolveRecordPath (path, record) {
1332
1379
 
1333
1380
  /* */
1334
1381
 
1335
- var inBrowser = typeof window !== 'undefined'
1336
1382
 
1337
- var supportsHistory = inBrowser && (function () {
1338
- var ua = window.navigator.userAgent
1383
+ var positionStore = Object.create(null);
1384
+
1385
+ function setupScroll () {
1386
+ window.addEventListener('popstate', function (e) {
1387
+ saveScrollPosition();
1388
+ if (e.state && e.state.key) {
1389
+ setStateKey(e.state.key);
1390
+ }
1391
+ });
1392
+ }
1393
+
1394
+ function handleScroll (
1395
+ router,
1396
+ to,
1397
+ from,
1398
+ isPop
1399
+ ) {
1400
+ if (!router.app) {
1401
+ return
1402
+ }
1403
+
1404
+ var behavior = router.options.scrollBehavior;
1405
+ if (!behavior) {
1406
+ return
1407
+ }
1408
+
1409
+ {
1410
+ assert(typeof behavior === 'function', "scrollBehavior must be a function");
1411
+ }
1412
+
1413
+ // wait until re-render finishes before scrolling
1414
+ router.app.$nextTick(function () {
1415
+ var position = getScrollPosition();
1416
+ var shouldScroll = behavior(to, from, isPop ? position : null);
1417
+ if (!shouldScroll) {
1418
+ return
1419
+ }
1420
+ var isObject = typeof shouldScroll === 'object';
1421
+ if (isObject && typeof shouldScroll.selector === 'string') {
1422
+ var el = document.querySelector(shouldScroll.selector);
1423
+ if (el) {
1424
+ position = getElementPosition(el);
1425
+ } else if (isValidPosition(shouldScroll)) {
1426
+ position = normalizePosition(shouldScroll);
1427
+ }
1428
+ } else if (isObject && isValidPosition(shouldScroll)) {
1429
+ position = normalizePosition(shouldScroll);
1430
+ }
1431
+
1432
+ if (position) {
1433
+ window.scrollTo(position.x, position.y);
1434
+ }
1435
+ });
1436
+ }
1437
+
1438
+ function saveScrollPosition () {
1439
+ var key = getStateKey();
1440
+ if (key) {
1441
+ positionStore[key] = {
1442
+ x: window.pageXOffset,
1443
+ y: window.pageYOffset
1444
+ };
1445
+ }
1446
+ }
1447
+
1448
+ function getScrollPosition () {
1449
+ var key = getStateKey();
1450
+ if (key) {
1451
+ return positionStore[key]
1452
+ }
1453
+ }
1454
+
1455
+ function getElementPosition (el) {
1456
+ var docRect = document.documentElement.getBoundingClientRect();
1457
+ var elRect = el.getBoundingClientRect();
1458
+ return {
1459
+ x: elRect.left - docRect.left,
1460
+ y: elRect.top - docRect.top
1461
+ }
1462
+ }
1463
+
1464
+ function isValidPosition (obj) {
1465
+ return isNumber(obj.x) || isNumber(obj.y)
1466
+ }
1467
+
1468
+ function normalizePosition (obj) {
1469
+ return {
1470
+ x: isNumber(obj.x) ? obj.x : window.pageXOffset,
1471
+ y: isNumber(obj.y) ? obj.y : window.pageYOffset
1472
+ }
1473
+ }
1474
+
1475
+ function isNumber (v) {
1476
+ return typeof v === 'number'
1477
+ }
1478
+
1479
+ /* */
1480
+
1481
+ var supportsPushState = inBrowser && (function () {
1482
+ var ua = window.navigator.userAgent;
1339
1483
 
1340
1484
  if (
1341
1485
  (ua.indexOf('Android 2.') !== -1 || ua.indexOf('Android 4.0') !== -1) &&
@@ -1347,64 +1491,127 @@ var supportsHistory = inBrowser && (function () {
1347
1491
  }
1348
1492
 
1349
1493
  return window.history && 'pushState' in window.history
1350
- })()
1494
+ })();
1495
+
1496
+ // use User Timing api (if present) for more accurate key precision
1497
+ var Time = inBrowser && window.performance && window.performance.now
1498
+ ? window.performance
1499
+ : Date;
1500
+
1501
+ var _key = genKey();
1502
+
1503
+ function genKey () {
1504
+ return Time.now().toFixed(3)
1505
+ }
1506
+
1507
+ function getStateKey () {
1508
+ return _key
1509
+ }
1510
+
1511
+ function setStateKey (key) {
1512
+ _key = key;
1513
+ }
1514
+
1515
+ function pushState (url, replace) {
1516
+ saveScrollPosition();
1517
+ // try...catch the pushState call to get around Safari
1518
+ // DOM Exception 18 where it limits to 100 pushState calls
1519
+ var history = window.history;
1520
+ try {
1521
+ if (replace) {
1522
+ history.replaceState({ key: _key }, '', url);
1523
+ } else {
1524
+ _key = genKey();
1525
+ history.pushState({ key: _key }, '', url);
1526
+ }
1527
+ } catch (e) {
1528
+ window.location[replace ? 'replace' : 'assign'](url);
1529
+ }
1530
+ }
1531
+
1532
+ function replaceState (url) {
1533
+ pushState(url, true);
1534
+ }
1351
1535
 
1352
1536
  /* */
1353
1537
 
1354
1538
  function runQueue (queue, fn, cb) {
1355
1539
  var step = function (index) {
1356
1540
  if (index >= queue.length) {
1357
- cb()
1541
+ cb();
1358
1542
  } else {
1359
1543
  if (queue[index]) {
1360
1544
  fn(queue[index], function () {
1361
- step(index + 1)
1362
- })
1545
+ step(index + 1);
1546
+ });
1363
1547
  } else {
1364
- step(index + 1)
1548
+ step(index + 1);
1365
1549
  }
1366
1550
  }
1367
- }
1368
- step(0)
1551
+ };
1552
+ step(0);
1369
1553
  }
1370
1554
 
1371
1555
  /* */
1372
1556
 
1373
1557
 
1374
1558
  var History = function History (router, base) {
1375
- this.router = router
1376
- this.base = normalizeBase(base)
1559
+ this.router = router;
1560
+ this.base = normalizeBase(base);
1377
1561
  // start with a route object that stands for "nowhere"
1378
- this.current = START
1379
- this.pending = null
1562
+ this.current = START;
1563
+ this.pending = null;
1564
+ this.ready = false;
1565
+ this.readyCbs = [];
1380
1566
  };
1381
1567
 
1382
1568
  History.prototype.listen = function listen (cb) {
1383
- this.cb = cb
1569
+ this.cb = cb;
1570
+ };
1571
+
1572
+ History.prototype.onReady = function onReady (cb) {
1573
+ if (this.ready) {
1574
+ cb();
1575
+ } else {
1576
+ this.readyCbs.push(cb);
1577
+ }
1384
1578
  };
1385
1579
 
1386
1580
  History.prototype.transitionTo = function transitionTo (location, onComplete, onAbort) {
1387
1581
  var this$1 = this;
1388
1582
 
1389
- var route = this.router.match(location, this.current)
1583
+ var route = this.router.match(location, this.current);
1390
1584
  this.confirmTransition(route, function () {
1391
- this$1.updateRoute(route)
1392
- onComplete && onComplete(route)
1393
- this$1.ensureURL()
1394
- }, onAbort)
1585
+ this$1.updateRoute(route);
1586
+ onComplete && onComplete(route);
1587
+ this$1.ensureURL();
1588
+
1589
+ // fire ready cbs once
1590
+ if (!this$1.ready) {
1591
+ this$1.ready = true;
1592
+ this$1.readyCbs.forEach(function (cb) {
1593
+ cb(route);
1594
+ });
1595
+ }
1596
+ }, onAbort);
1395
1597
  };
1396
1598
 
1397
1599
  History.prototype.confirmTransition = function confirmTransition (route, onComplete, onAbort) {
1398
1600
  var this$1 = this;
1399
1601
 
1400
- var current = this.current
1401
- var abort = function () { onAbort && onAbort() }
1402
- if (isSameRoute(route, current)) {
1403
- this.ensureURL()
1602
+ var current = this.current;
1603
+ var abort = function () { onAbort && onAbort(); };
1604
+ if (
1605
+ isSameRoute(route, current) &&
1606
+ // in the case the route map has been dynamically appended to
1607
+ route.matched.length === current.matched.length
1608
+ ) {
1609
+ this.ensureURL();
1404
1610
  return abort()
1405
1611
  }
1406
1612
 
1407
1613
  var ref = resolveQueue(this.current.matched, route.matched);
1614
+ var updated = ref.updated;
1408
1615
  var deactivated = ref.deactivated;
1409
1616
  var activated = ref.activated;
1410
1617
 
@@ -1413,13 +1620,15 @@ History.prototype.confirmTransition = function confirmTransition (route, onCompl
1413
1620
  extractLeaveGuards(deactivated),
1414
1621
  // global before hooks
1415
1622
  this.router.beforeHooks,
1416
- // enter guards
1623
+ // in-component update hooks
1624
+ extractUpdateHooks(updated),
1625
+ // in-config enter guards
1417
1626
  activated.map(function (m) { return m.beforeEnter; }),
1418
1627
  // async components
1419
1628
  resolveAsyncComponents(activated)
1420
- )
1629
+ );
1421
1630
 
1422
- this.pending = route
1631
+ this.pending = route;
1423
1632
  var iterator = function (hook, next) {
1424
1633
  if (this$1.pending !== route) {
1425
1634
  return abort()
@@ -1427,63 +1636,62 @@ History.prototype.confirmTransition = function confirmTransition (route, onCompl
1427
1636
  hook(route, current, function (to) {
1428
1637
  if (to === false) {
1429
1638
  // next(false) -> abort navigation, ensure current URL
1430
- this$1.ensureURL(true)
1431
- abort()
1639
+ this$1.ensureURL(true);
1640
+ abort();
1432
1641
  } else if (typeof to === 'string' || typeof to === 'object') {
1433
1642
  // next('/') or next({ path: '/' }) -> redirect
1434
- (typeof to === 'object' && to.replace) ? this$1.replace(to) : this$1.push(to)
1435
- abort()
1643
+ (typeof to === 'object' && to.replace) ? this$1.replace(to) : this$1.push(to);
1644
+ abort();
1436
1645
  } else {
1437
1646
  // confirm transition and pass on the value
1438
- next(to)
1647
+ next(to);
1439
1648
  }
1440
- })
1441
- }
1649
+ });
1650
+ };
1442
1651
 
1443
1652
  runQueue(queue, iterator, function () {
1444
- var postEnterCbs = []
1445
- var enterGuards = extractEnterGuards(activated, postEnterCbs, function () {
1446
- return this$1.current === route
1447
- })
1653
+ var postEnterCbs = [];
1654
+ var isValid = function () { return this$1.current === route; };
1655
+ var enterGuards = extractEnterGuards(activated, postEnterCbs, isValid);
1448
1656
  // wait until async components are resolved before
1449
1657
  // extracting in-component enter guards
1450
1658
  runQueue(enterGuards, iterator, function () {
1451
1659
  if (this$1.pending !== route) {
1452
1660
  return abort()
1453
1661
  }
1454
- this$1.pending = null
1455
- onComplete(route)
1662
+ this$1.pending = null;
1663
+ onComplete(route);
1456
1664
  if (this$1.router.app) {
1457
1665
  this$1.router.app.$nextTick(function () {
1458
- postEnterCbs.forEach(function (cb) { return cb(); })
1459
- })
1666
+ postEnterCbs.forEach(function (cb) { return cb(); });
1667
+ });
1460
1668
  }
1461
- })
1462
- })
1669
+ });
1670
+ });
1463
1671
  };
1464
1672
 
1465
1673
  History.prototype.updateRoute = function updateRoute (route) {
1466
- var prev = this.current
1467
- this.current = route
1468
- this.cb && this.cb(route)
1674
+ var prev = this.current;
1675
+ this.current = route;
1676
+ this.cb && this.cb(route);
1469
1677
  this.router.afterHooks.forEach(function (hook) {
1470
- hook && hook(route, prev)
1471
- })
1678
+ hook && hook(route, prev);
1679
+ });
1472
1680
  };
1473
1681
 
1474
1682
  function normalizeBase (base) {
1475
1683
  if (!base) {
1476
1684
  if (inBrowser) {
1477
1685
  // respect <base> tag
1478
- var baseEl = document.querySelector('base')
1479
- base = baseEl ? baseEl.getAttribute('href') : '/'
1686
+ var baseEl = document.querySelector('base');
1687
+ base = baseEl ? baseEl.getAttribute('href') : '/';
1480
1688
  } else {
1481
- base = '/'
1689
+ base = '/';
1482
1690
  }
1483
1691
  }
1484
1692
  // make sure there's the starting slash
1485
1693
  if (base.charAt(0) !== '/') {
1486
- base = '/' + base
1694
+ base = '/' + base;
1487
1695
  }
1488
1696
  // remove trailing slash
1489
1697
  return base.replace(/\/$/, '')
@@ -1493,75 +1701,82 @@ function resolveQueue (
1493
1701
  current,
1494
1702
  next
1495
1703
  ) {
1496
- var i
1497
- var max = Math.max(current.length, next.length)
1704
+ var i;
1705
+ var max = Math.max(current.length, next.length);
1498
1706
  for (i = 0; i < max; i++) {
1499
1707
  if (current[i] !== next[i]) {
1500
1708
  break
1501
1709
  }
1502
1710
  }
1503
1711
  return {
1712
+ updated: next.slice(0, i),
1504
1713
  activated: next.slice(i),
1505
1714
  deactivated: current.slice(i)
1506
1715
  }
1507
1716
  }
1508
1717
 
1718
+ function extractGuards (
1719
+ records,
1720
+ name,
1721
+ bind,
1722
+ reverse
1723
+ ) {
1724
+ var guards = flatMapComponents(records, function (def, instance, match, key) {
1725
+ var guard = extractGuard(def, name);
1726
+ if (guard) {
1727
+ return Array.isArray(guard)
1728
+ ? guard.map(function (guard) { return bind(guard, instance, match, key); })
1729
+ : bind(guard, instance, match, key)
1730
+ }
1731
+ });
1732
+ return flatten(reverse ? guards.reverse() : guards)
1733
+ }
1734
+
1509
1735
  function extractGuard (
1510
1736
  def,
1511
1737
  key
1512
1738
  ) {
1513
1739
  if (typeof def !== 'function') {
1514
1740
  // extend now so that global mixins are applied.
1515
- def = _Vue.extend(def)
1741
+ def = _Vue.extend(def);
1516
1742
  }
1517
1743
  return def.options[key]
1518
1744
  }
1519
1745
 
1520
- function extractLeaveGuards (matched) {
1521
- return flatten(flatMapComponents(matched, function (def, instance) {
1522
- var guard = extractGuard(def, 'beforeRouteLeave')
1523
- if (guard) {
1524
- return Array.isArray(guard)
1525
- ? guard.map(function (guard) { return wrapLeaveGuard(guard, instance); })
1526
- : wrapLeaveGuard(guard, instance)
1527
- }
1528
- }).reverse())
1746
+ function extractLeaveGuards (deactivated) {
1747
+ return extractGuards(deactivated, 'beforeRouteLeave', bindGuard, true)
1529
1748
  }
1530
1749
 
1531
- function wrapLeaveGuard (
1532
- guard,
1533
- instance
1534
- ) {
1535
- return function routeLeaveGuard () {
1750
+ function extractUpdateHooks (updated) {
1751
+ return extractGuards(updated, 'beforeRouteUpdate', bindGuard)
1752
+ }
1753
+
1754
+ function bindGuard (guard, instance) {
1755
+ return function boundRouteGuard () {
1536
1756
  return guard.apply(instance, arguments)
1537
1757
  }
1538
1758
  }
1539
1759
 
1540
1760
  function extractEnterGuards (
1541
- matched,
1761
+ activated,
1542
1762
  cbs,
1543
1763
  isValid
1544
1764
  ) {
1545
- return flatten(flatMapComponents(matched, function (def, _, match, key) {
1546
- var guard = extractGuard(def, 'beforeRouteEnter')
1547
- if (guard) {
1548
- return Array.isArray(guard)
1549
- ? guard.map(function (guard) { return wrapEnterGuard(guard, cbs, match, key, isValid); })
1550
- : wrapEnterGuard(guard, cbs, match, key, isValid)
1551
- }
1552
- }))
1765
+ return extractGuards(activated, 'beforeRouteEnter', function (guard, _, match, key) {
1766
+ return bindEnterGuard(guard, match, key, cbs, isValid)
1767
+ })
1553
1768
  }
1554
1769
 
1555
- function wrapEnterGuard (
1770
+ function bindEnterGuard (
1556
1771
  guard,
1557
- cbs,
1558
1772
  match,
1559
1773
  key,
1774
+ cbs,
1560
1775
  isValid
1561
1776
  ) {
1562
1777
  return function routeEnterGuard (to, from, next) {
1563
1778
  return guard(to, from, function (cb) {
1564
- next(cb)
1779
+ next(cb);
1565
1780
  if (typeof cb === 'function') {
1566
1781
  cbs.push(function () {
1567
1782
  // #750
@@ -1569,8 +1784,8 @@ function wrapEnterGuard (
1569
1784
  // the instance may not have been registered at this time.
1570
1785
  // we will need to poll for registration until current route
1571
1786
  // is no longer valid.
1572
- poll(cb, match.instances, key, isValid)
1573
- })
1787
+ poll(cb, match.instances, key, isValid);
1788
+ });
1574
1789
  }
1575
1790
  })
1576
1791
  }
@@ -1583,11 +1798,11 @@ function poll (
1583
1798
  isValid
1584
1799
  ) {
1585
1800
  if (instances[key]) {
1586
- cb(instances[key])
1801
+ cb(instances[key]);
1587
1802
  } else if (isValid()) {
1588
1803
  setTimeout(function () {
1589
- poll(cb, instances, key, isValid)
1590
- }, 16)
1804
+ poll(cb, instances, key, isValid);
1805
+ }, 16);
1591
1806
  }
1592
1807
  }
1593
1808
 
@@ -1600,19 +1815,19 @@ function resolveAsyncComponents (matched) {
1600
1815
  // resolved.
1601
1816
  if (typeof def === 'function' && !def.options) {
1602
1817
  return function (to, from, next) {
1603
- var resolve = function (resolvedDef) {
1604
- match.components[key] = resolvedDef
1605
- next()
1606
- }
1818
+ var resolve = once(function (resolvedDef) {
1819
+ match.components[key] = resolvedDef;
1820
+ next();
1821
+ });
1607
1822
 
1608
- var reject = function (reason) {
1609
- warn(false, ("Failed to resolve async component " + key + ": " + reason))
1610
- next(false)
1611
- }
1823
+ var reject = once(function (reason) {
1824
+ warn(false, ("Failed to resolve async component " + key + ": " + reason));
1825
+ next(false);
1826
+ });
1612
1827
 
1613
- var res = def(resolve, reject)
1828
+ var res = def(resolve, reject);
1614
1829
  if (res && typeof res.then === 'function') {
1615
- res.then(resolve, reject)
1830
+ res.then(resolve, reject);
1616
1831
  }
1617
1832
  }
1618
1833
  }
@@ -1636,321 +1851,245 @@ function flatten (arr) {
1636
1851
  return Array.prototype.concat.apply([], arr)
1637
1852
  }
1638
1853
 
1639
- /* */
1640
-
1641
- var positionStore = Object.create(null)
1642
-
1643
- function saveScrollPosition (key) {
1644
- if (!key) { return }
1645
- positionStore[key] = {
1646
- x: window.pageXOffset,
1647
- y: window.pageYOffset
1648
- }
1649
- }
1650
-
1651
- function getScrollPosition (key) {
1652
- if (!key) { return }
1653
- return positionStore[key]
1654
- }
1655
-
1656
- function getElementPosition (el) {
1657
- var docRect = document.documentElement.getBoundingClientRect()
1658
- var elRect = el.getBoundingClientRect()
1659
- return {
1660
- x: elRect.left - docRect.left,
1661
- y: elRect.top - docRect.top
1662
- }
1663
- }
1664
-
1665
- function isValidPosition (obj) {
1666
- return isNumber(obj.x) || isNumber(obj.y)
1667
- }
1668
-
1669
- function normalizePosition (obj) {
1670
- return {
1671
- x: isNumber(obj.x) ? obj.x : window.pageXOffset,
1672
- y: isNumber(obj.y) ? obj.y : window.pageYOffset
1854
+ // in Webpack 2, require.ensure now also returns a Promise
1855
+ // so the resolve/reject functions may get called an extra time
1856
+ // if the user uses an arrow function shorthand that happens to
1857
+ // return that Promise.
1858
+ function once (fn) {
1859
+ var called = false;
1860
+ return function () {
1861
+ if (called) { return }
1862
+ called = true;
1863
+ return fn.apply(this, arguments)
1673
1864
  }
1674
1865
  }
1675
1866
 
1676
- function isNumber (v) {
1677
- return typeof v === 'number'
1678
- }
1679
-
1680
1867
  /* */
1681
1868
 
1682
1869
 
1683
- // use User Timing api (if present) for more accurate key precision
1684
- var Time = inBrowser && window.performance && window.performance.now
1685
- ? window.performance
1686
- : Date
1687
-
1688
- var genKey = function () { return String(Time.now()); }
1689
- var _key = genKey()
1690
-
1691
- var HTML5History = (function (History) {
1870
+ var HTML5History = (function (History$$1) {
1692
1871
  function HTML5History (router, base) {
1693
1872
  var this$1 = this;
1694
1873
 
1695
- History.call(this, router, base)
1874
+ History$$1.call(this, router, base);
1696
1875
 
1697
- var expectScroll = router.options.scrollBehavior
1698
- window.addEventListener('popstate', function (e) {
1699
- _key = e.state && e.state.key
1700
- var current = this$1.current
1701
- this$1.transitionTo(getLocation(this$1.base), function (next) {
1702
- if (expectScroll) {
1703
- this$1.handleScroll(next, current, true)
1704
- }
1705
- })
1706
- })
1876
+ var expectScroll = router.options.scrollBehavior;
1707
1877
 
1708
1878
  if (expectScroll) {
1709
- window.addEventListener('scroll', function () {
1710
- saveScrollPosition(_key)
1711
- })
1879
+ setupScroll();
1712
1880
  }
1881
+
1882
+ window.addEventListener('popstate', function (e) {
1883
+ this$1.transitionTo(getLocation(this$1.base), function (route) {
1884
+ if (expectScroll) {
1885
+ handleScroll(router, route, this$1.current, true);
1886
+ }
1887
+ });
1888
+ });
1713
1889
  }
1714
1890
 
1715
- if ( History ) HTML5History.__proto__ = History;
1716
- HTML5History.prototype = Object.create( History && History.prototype );
1891
+ if ( History$$1 ) HTML5History.__proto__ = History$$1;
1892
+ HTML5History.prototype = Object.create( History$$1 && History$$1.prototype );
1717
1893
  HTML5History.prototype.constructor = HTML5History;
1718
1894
 
1719
1895
  HTML5History.prototype.go = function go (n) {
1720
- window.history.go(n)
1896
+ window.history.go(n);
1721
1897
  };
1722
1898
 
1723
- HTML5History.prototype.push = function push (location) {
1899
+ HTML5History.prototype.push = function push (location, onComplete, onAbort) {
1724
1900
  var this$1 = this;
1725
1901
 
1726
- var current = this.current
1727
1902
  this.transitionTo(location, function (route) {
1728
- pushState(cleanPath(this$1.base + route.fullPath))
1729
- this$1.handleScroll(route, current, false)
1730
- })
1903
+ pushState(cleanPath(this$1.base + route.fullPath));
1904
+ handleScroll(this$1.router, route, this$1.current, false);
1905
+ onComplete && onComplete(route);
1906
+ }, onAbort);
1731
1907
  };
1732
1908
 
1733
- HTML5History.prototype.replace = function replace (location) {
1909
+ HTML5History.prototype.replace = function replace (location, onComplete, onAbort) {
1734
1910
  var this$1 = this;
1735
1911
 
1736
- var current = this.current
1737
1912
  this.transitionTo(location, function (route) {
1738
- replaceState(cleanPath(this$1.base + route.fullPath))
1739
- this$1.handleScroll(route, current, false)
1740
- })
1913
+ replaceState(cleanPath(this$1.base + route.fullPath));
1914
+ handleScroll(this$1.router, route, this$1.current, false);
1915
+ onComplete && onComplete(route);
1916
+ }, onAbort);
1741
1917
  };
1742
1918
 
1743
1919
  HTML5History.prototype.ensureURL = function ensureURL (push) {
1744
1920
  if (getLocation(this.base) !== this.current.fullPath) {
1745
- var current = cleanPath(this.base + this.current.fullPath)
1746
- push ? pushState(current) : replaceState(current)
1921
+ var current = cleanPath(this.base + this.current.fullPath);
1922
+ push ? pushState(current) : replaceState(current);
1747
1923
  }
1748
1924
  };
1749
1925
 
1750
- HTML5History.prototype.handleScroll = function handleScroll (to, from, isPop) {
1751
- var router = this.router
1752
- if (!router.app) {
1753
- return
1754
- }
1755
-
1756
- var behavior = router.options.scrollBehavior
1757
- if (!behavior) {
1758
- return
1759
- }
1760
- if ("development" !== 'production') {
1761
- assert(typeof behavior === 'function', "scrollBehavior must be a function")
1762
- }
1763
-
1764
- // wait until re-render finishes before scrolling
1765
- router.app.$nextTick(function () {
1766
- var position = getScrollPosition(_key)
1767
- var shouldScroll = behavior(to, from, isPop ? position : null)
1768
- if (!shouldScroll) {
1769
- return
1770
- }
1771
- var isObject = typeof shouldScroll === 'object'
1772
- if (isObject && typeof shouldScroll.selector === 'string') {
1773
- var el = document.querySelector(shouldScroll.selector)
1774
- if (el) {
1775
- position = getElementPosition(el)
1776
- } else if (isValidPosition(shouldScroll)) {
1777
- position = normalizePosition(shouldScroll)
1778
- }
1779
- } else if (isObject && isValidPosition(shouldScroll)) {
1780
- position = normalizePosition(shouldScroll)
1781
- }
1782
-
1783
- if (position) {
1784
- window.scrollTo(position.x, position.y)
1785
- }
1786
- })
1926
+ HTML5History.prototype.getCurrentLocation = function getCurrentLocation () {
1927
+ return getLocation(this.base)
1787
1928
  };
1788
1929
 
1789
1930
  return HTML5History;
1790
1931
  }(History));
1791
1932
 
1792
1933
  function getLocation (base) {
1793
- var path = window.location.pathname
1934
+ var path = window.location.pathname;
1794
1935
  if (base && path.indexOf(base) === 0) {
1795
- path = path.slice(base.length)
1936
+ path = path.slice(base.length);
1796
1937
  }
1797
1938
  return (path || '/') + window.location.search + window.location.hash
1798
1939
  }
1799
1940
 
1800
- function pushState (url, replace) {
1801
- // try...catch the pushState call to get around Safari
1802
- // DOM Exception 18 where it limits to 100 pushState calls
1803
- var history = window.history
1804
- try {
1805
- if (replace) {
1806
- history.replaceState({ key: _key }, '', url)
1807
- } else {
1808
- _key = genKey()
1809
- history.pushState({ key: _key }, '', url)
1810
- }
1811
- saveScrollPosition(_key)
1812
- } catch (e) {
1813
- window.location[replace ? 'replace' : 'assign'](url)
1814
- }
1815
- }
1816
-
1817
- function replaceState (url) {
1818
- pushState(url, true)
1819
- }
1820
-
1821
1941
  /* */
1822
1942
 
1823
1943
 
1824
- var HashHistory = (function (History) {
1944
+ var HashHistory = (function (History$$1) {
1825
1945
  function HashHistory (router, base, fallback) {
1826
- History.call(this, router, base)
1946
+ History$$1.call(this, router, base);
1827
1947
  // check history fallback deeplinking
1828
- if (fallback && this.checkFallback()) {
1948
+ if (fallback && checkFallback(this.base)) {
1829
1949
  return
1830
1950
  }
1831
- ensureSlash()
1951
+ ensureSlash();
1832
1952
  }
1833
1953
 
1834
- if ( History ) HashHistory.__proto__ = History;
1835
- HashHistory.prototype = Object.create( History && History.prototype );
1954
+ if ( History$$1 ) HashHistory.__proto__ = History$$1;
1955
+ HashHistory.prototype = Object.create( History$$1 && History$$1.prototype );
1836
1956
  HashHistory.prototype.constructor = HashHistory;
1837
1957
 
1838
- HashHistory.prototype.checkFallback = function checkFallback () {
1839
- var location = getLocation(this.base)
1840
- if (!/^\/#/.test(location)) {
1841
- window.location.replace(
1842
- cleanPath(this.base + '/#' + location)
1843
- )
1844
- return true
1845
- }
1846
- };
1958
+ // this is delayed until the app mounts
1959
+ // to avoid the hashchange listener being fired too early
1960
+ HashHistory.prototype.setupListeners = function setupListeners () {
1961
+ var this$1 = this;
1847
1962
 
1848
- HashHistory.prototype.onHashChange = function onHashChange () {
1849
- if (!ensureSlash()) {
1850
- return
1851
- }
1852
- this.transitionTo(getHash(), function (route) {
1853
- replaceHash(route.fullPath)
1854
- })
1963
+ window.addEventListener('hashchange', function () {
1964
+ if (!ensureSlash()) {
1965
+ return
1966
+ }
1967
+ this$1.transitionTo(getHash(), function (route) {
1968
+ replaceHash(route.fullPath);
1969
+ });
1970
+ });
1855
1971
  };
1856
1972
 
1857
- HashHistory.prototype.push = function push (location) {
1973
+ HashHistory.prototype.push = function push (location, onComplete, onAbort) {
1858
1974
  this.transitionTo(location, function (route) {
1859
- pushHash(route.fullPath)
1860
- })
1975
+ pushHash(route.fullPath);
1976
+ onComplete && onComplete(route);
1977
+ }, onAbort);
1861
1978
  };
1862
1979
 
1863
- HashHistory.prototype.replace = function replace (location) {
1980
+ HashHistory.prototype.replace = function replace (location, onComplete, onAbort) {
1864
1981
  this.transitionTo(location, function (route) {
1865
- replaceHash(route.fullPath)
1866
- })
1982
+ replaceHash(route.fullPath);
1983
+ onComplete && onComplete(route);
1984
+ }, onAbort);
1867
1985
  };
1868
1986
 
1869
1987
  HashHistory.prototype.go = function go (n) {
1870
- window.history.go(n)
1988
+ window.history.go(n);
1871
1989
  };
1872
1990
 
1873
1991
  HashHistory.prototype.ensureURL = function ensureURL (push) {
1874
- var current = this.current.fullPath
1992
+ var current = this.current.fullPath;
1875
1993
  if (getHash() !== current) {
1876
- push ? pushHash(current) : replaceHash(current)
1994
+ push ? pushHash(current) : replaceHash(current);
1877
1995
  }
1878
1996
  };
1879
1997
 
1998
+ HashHistory.prototype.getCurrentLocation = function getCurrentLocation () {
1999
+ return getHash()
2000
+ };
2001
+
1880
2002
  return HashHistory;
1881
2003
  }(History));
1882
2004
 
2005
+ function checkFallback (base) {
2006
+ var location = getLocation(base);
2007
+ if (!/^\/#/.test(location)) {
2008
+ window.location.replace(
2009
+ cleanPath(base + '/#' + location)
2010
+ );
2011
+ return true
2012
+ }
2013
+ }
2014
+
1883
2015
  function ensureSlash () {
1884
- var path = getHash()
2016
+ var path = getHash();
1885
2017
  if (path.charAt(0) === '/') {
1886
2018
  return true
1887
2019
  }
1888
- replaceHash('/' + path)
2020
+ replaceHash('/' + path);
1889
2021
  return false
1890
2022
  }
1891
2023
 
1892
2024
  function getHash () {
1893
2025
  // We can't use window.location.hash here because it's not
1894
2026
  // consistent across browsers - Firefox will pre-decode it!
1895
- var href = window.location.href
1896
- var index = href.indexOf('#')
2027
+ var href = window.location.href;
2028
+ var index = href.indexOf('#');
1897
2029
  return index === -1 ? '' : href.slice(index + 1)
1898
2030
  }
1899
2031
 
1900
2032
  function pushHash (path) {
1901
- window.location.hash = path
2033
+ window.location.hash = path;
1902
2034
  }
1903
2035
 
1904
2036
  function replaceHash (path) {
1905
- var i = window.location.href.indexOf('#')
2037
+ var i = window.location.href.indexOf('#');
1906
2038
  window.location.replace(
1907
2039
  window.location.href.slice(0, i >= 0 ? i : 0) + '#' + path
1908
- )
2040
+ );
1909
2041
  }
1910
2042
 
1911
2043
  /* */
1912
2044
 
1913
2045
 
1914
- var AbstractHistory = (function (History) {
2046
+ var AbstractHistory = (function (History$$1) {
1915
2047
  function AbstractHistory (router, base) {
1916
- History.call(this, router, base)
1917
- this.stack = []
1918
- this.index = -1
2048
+ History$$1.call(this, router, base);
2049
+ this.stack = [];
2050
+ this.index = -1;
1919
2051
  }
1920
2052
 
1921
- if ( History ) AbstractHistory.__proto__ = History;
1922
- AbstractHistory.prototype = Object.create( History && History.prototype );
2053
+ if ( History$$1 ) AbstractHistory.__proto__ = History$$1;
2054
+ AbstractHistory.prototype = Object.create( History$$1 && History$$1.prototype );
1923
2055
  AbstractHistory.prototype.constructor = AbstractHistory;
1924
2056
 
1925
- AbstractHistory.prototype.push = function push (location) {
2057
+ AbstractHistory.prototype.push = function push (location, onComplete, onAbort) {
1926
2058
  var this$1 = this;
1927
2059
 
1928
2060
  this.transitionTo(location, function (route) {
1929
- this$1.stack = this$1.stack.slice(0, this$1.index + 1).concat(route)
1930
- this$1.index++
1931
- })
2061
+ this$1.stack = this$1.stack.slice(0, this$1.index + 1).concat(route);
2062
+ this$1.index++;
2063
+ onComplete && onComplete(route);
2064
+ }, onAbort);
1932
2065
  };
1933
2066
 
1934
- AbstractHistory.prototype.replace = function replace (location) {
2067
+ AbstractHistory.prototype.replace = function replace (location, onComplete, onAbort) {
1935
2068
  var this$1 = this;
1936
2069
 
1937
2070
  this.transitionTo(location, function (route) {
1938
- this$1.stack = this$1.stack.slice(0, this$1.index).concat(route)
1939
- })
2071
+ this$1.stack = this$1.stack.slice(0, this$1.index).concat(route);
2072
+ onComplete && onComplete(route);
2073
+ }, onAbort);
1940
2074
  };
1941
2075
 
1942
2076
  AbstractHistory.prototype.go = function go (n) {
1943
2077
  var this$1 = this;
1944
2078
 
1945
- var targetIndex = this.index + n
2079
+ var targetIndex = this.index + n;
1946
2080
  if (targetIndex < 0 || targetIndex >= this.stack.length) {
1947
2081
  return
1948
2082
  }
1949
- var route = this.stack[targetIndex]
2083
+ var route = this.stack[targetIndex];
1950
2084
  this.confirmTransition(route, function () {
1951
- this$1.index = targetIndex
1952
- this$1.updateRoute(route)
1953
- })
2085
+ this$1.index = targetIndex;
2086
+ this$1.updateRoute(route);
2087
+ });
2088
+ };
2089
+
2090
+ AbstractHistory.prototype.getCurrentLocation = function getCurrentLocation () {
2091
+ var current = this.stack[this.stack.length - 1];
2092
+ return current ? current.fullPath : '/'
1954
2093
  };
1955
2094
 
1956
2095
  AbstractHistory.prototype.ensureURL = function ensureURL () {
@@ -1965,39 +2104,50 @@ var AbstractHistory = (function (History) {
1965
2104
  var VueRouter = function VueRouter (options) {
1966
2105
  if ( options === void 0 ) options = {};
1967
2106
 
1968
- this.app = null
1969
- this.options = options
1970
- this.beforeHooks = []
1971
- this.afterHooks = []
1972
- this.match = createMatcher(options.routes || [])
2107
+ this.app = null;
2108
+ this.apps = [];
2109
+ this.options = options;
2110
+ this.beforeHooks = [];
2111
+ this.afterHooks = [];
2112
+ this.matcher = createMatcher(options.routes || []);
1973
2113
 
1974
- var mode = options.mode || 'hash'
1975
- this.fallback = mode === 'history' && !supportsHistory
2114
+ var mode = options.mode || 'hash';
2115
+ this.fallback = mode === 'history' && !supportsPushState;
1976
2116
  if (this.fallback) {
1977
- mode = 'hash'
2117
+ mode = 'hash';
1978
2118
  }
1979
2119
  if (!inBrowser) {
1980
- mode = 'abstract'
2120
+ mode = 'abstract';
1981
2121
  }
1982
- this.mode = mode
2122
+ this.mode = mode;
1983
2123
 
1984
2124
  switch (mode) {
1985
2125
  case 'history':
1986
- this.history = new HTML5History(this, options.base)
2126
+ this.history = new HTML5History(this, options.base);
1987
2127
  break
1988
2128
  case 'hash':
1989
- this.history = new HashHistory(this, options.base, this.fallback)
2129
+ this.history = new HashHistory(this, options.base, this.fallback);
1990
2130
  break
1991
2131
  case 'abstract':
1992
- this.history = new AbstractHistory(this, options.base)
2132
+ this.history = new AbstractHistory(this, options.base);
1993
2133
  break
1994
2134
  default:
1995
- "development" !== 'production' && assert(false, ("invalid mode: " + mode))
2135
+ {
2136
+ assert(false, ("invalid mode: " + mode));
2137
+ }
1996
2138
  }
1997
2139
  };
1998
2140
 
1999
2141
  var prototypeAccessors = { currentRoute: {} };
2000
2142
 
2143
+ VueRouter.prototype.match = function match (
2144
+ raw,
2145
+ current,
2146
+ redirectedFrom
2147
+ ) {
2148
+ return this.matcher.match(raw, current, redirectedFrom)
2149
+ };
2150
+
2001
2151
  prototypeAccessors.currentRoute.get = function () {
2002
2152
  return this.history && this.history.current
2003
2153
  };
@@ -2009,60 +2159,75 @@ VueRouter.prototype.init = function init (app /* Vue component instance */) {
2009
2159
  install.installed,
2010
2160
  "not installed. Make sure to call `Vue.use(VueRouter)` " +
2011
2161
  "before creating root instance."
2012
- )
2162
+ );
2163
+
2164
+ this.apps.push(app);
2013
2165
 
2014
- this.app = app
2166
+ // main app already initialized.
2167
+ if (this.app) {
2168
+ return
2169
+ }
2170
+
2171
+ this.app = app;
2015
2172
 
2016
- var history = this.history
2173
+ var history = this.history;
2017
2174
 
2018
2175
  if (history instanceof HTML5History) {
2019
- history.transitionTo(getLocation(history.base))
2176
+ history.transitionTo(history.getCurrentLocation());
2020
2177
  } else if (history instanceof HashHistory) {
2021
2178
  var setupHashListener = function () {
2022
- window.addEventListener('hashchange', function () {
2023
- history.onHashChange()
2024
- })
2025
- }
2026
- history.transitionTo(getHash(), setupHashListener, setupHashListener)
2179
+ history.setupListeners();
2180
+ };
2181
+ history.transitionTo(
2182
+ history.getCurrentLocation(),
2183
+ setupHashListener,
2184
+ setupHashListener
2185
+ );
2027
2186
  }
2028
2187
 
2029
2188
  history.listen(function (route) {
2030
- this$1.app._route = route
2031
- })
2189
+ this$1.apps.forEach(function (app) {
2190
+ app._route = route;
2191
+ });
2192
+ });
2032
2193
  };
2033
2194
 
2034
2195
  VueRouter.prototype.beforeEach = function beforeEach (fn) {
2035
- this.beforeHooks.push(fn)
2196
+ this.beforeHooks.push(fn);
2036
2197
  };
2037
2198
 
2038
2199
  VueRouter.prototype.afterEach = function afterEach (fn) {
2039
- this.afterHooks.push(fn)
2200
+ this.afterHooks.push(fn);
2040
2201
  };
2041
2202
 
2042
- VueRouter.prototype.push = function push (location) {
2043
- this.history.push(location)
2203
+ VueRouter.prototype.onReady = function onReady (cb) {
2204
+ this.history.onReady(cb);
2044
2205
  };
2045
2206
 
2046
- VueRouter.prototype.replace = function replace (location) {
2047
- this.history.replace(location)
2207
+ VueRouter.prototype.push = function push (location, onComplete, onAbort) {
2208
+ this.history.push(location, onComplete, onAbort);
2209
+ };
2210
+
2211
+ VueRouter.prototype.replace = function replace (location, onComplete, onAbort) {
2212
+ this.history.replace(location, onComplete, onAbort);
2048
2213
  };
2049
2214
 
2050
2215
  VueRouter.prototype.go = function go (n) {
2051
- this.history.go(n)
2216
+ this.history.go(n);
2052
2217
  };
2053
2218
 
2054
2219
  VueRouter.prototype.back = function back () {
2055
- this.go(-1)
2220
+ this.go(-1);
2056
2221
  };
2057
2222
 
2058
2223
  VueRouter.prototype.forward = function forward () {
2059
- this.go(1)
2224
+ this.go(1);
2060
2225
  };
2061
2226
 
2062
2227
  VueRouter.prototype.getMatchedComponents = function getMatchedComponents (to) {
2063
2228
  var route = to
2064
- ? this.resolve(to).resolved
2065
- : this.currentRoute
2229
+ ? this.resolve(to).route
2230
+ : this.currentRoute;
2066
2231
  if (!route) {
2067
2232
  return []
2068
2233
  }
@@ -2078,32 +2243,42 @@ VueRouter.prototype.resolve = function resolve (
2078
2243
  current,
2079
2244
  append
2080
2245
  ) {
2081
- var normalizedTo = normalizeLocation(to, current || this.history.current, append)
2082
- var resolved = this.match(normalizedTo, current)
2083
- var fullPath = resolved.redirectedFrom || resolved.fullPath
2084
- var base = this.history.base
2085
- var href = createHref(base, fullPath, this.mode)
2246
+ var location = normalizeLocation(to, current || this.history.current, append);
2247
+ var route = this.match(location, current);
2248
+ var fullPath = route.redirectedFrom || route.fullPath;
2249
+ var base = this.history.base;
2250
+ var href = createHref(base, fullPath, this.mode);
2086
2251
  return {
2087
- normalizedTo: normalizedTo,
2088
- resolved: resolved,
2089
- href: href
2252
+ location: location,
2253
+ route: route,
2254
+ href: href,
2255
+ // for backwards compat
2256
+ normalizedTo: location,
2257
+ resolved: route
2258
+ }
2259
+ };
2260
+
2261
+ VueRouter.prototype.addRoutes = function addRoutes (routes) {
2262
+ this.matcher.addRoutes(routes);
2263
+ if (this.history.current !== START) {
2264
+ this.history.transitionTo(this.history.getCurrentLocation());
2090
2265
  }
2091
2266
  };
2092
2267
 
2093
2268
  Object.defineProperties( VueRouter.prototype, prototypeAccessors );
2094
2269
 
2095
2270
  function createHref (base, fullPath, mode) {
2096
- var path = mode === 'hash' ? '#' + fullPath : fullPath
2271
+ var path = mode === 'hash' ? '#' + fullPath : fullPath;
2097
2272
  return base ? cleanPath(base + '/' + path) : path
2098
2273
  }
2099
2274
 
2100
- VueRouter.install = install
2101
- VueRouter.version = '2.1.3'
2275
+ VueRouter.install = install;
2276
+ VueRouter.version = '2.2.1';
2102
2277
 
2103
2278
  if (inBrowser && window.Vue) {
2104
- window.Vue.use(VueRouter)
2279
+ window.Vue.use(VueRouter);
2105
2280
  }
2106
2281
 
2107
2282
  return VueRouter;
2108
2283
 
2109
- })));
2284
+ })));