kdu-router 3.0.7 → 3.1.7

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,5 +1,5 @@
1
1
  /*!
2
- * kdu-router v3.0.7
2
+ * kdu-router v3.1.7
3
3
  * (c) 2022 NKDuy
4
4
  * @license MIT
5
5
  */
@@ -23,6 +23,14 @@ function isError (err) {
23
23
  return Object.prototype.toString.call(err).indexOf('Error') > -1
24
24
  }
25
25
 
26
+ function isExtendedError (constructor, err) {
27
+ return (
28
+ err instanceof constructor ||
29
+ // _name is to support IE9 too
30
+ (err && (err.name === constructor.name || err._name === constructor._name))
31
+ )
32
+ }
33
+
26
34
  function extend (a, b) {
27
35
  for (var key in b) {
28
36
  a[key] = b[key];
@@ -60,14 +68,12 @@ var View = {
60
68
  var depth = 0;
61
69
  var inactive = false;
62
70
  while (parent && parent._routerRoot !== parent) {
63
- var knodeData = parent.$knode && parent.$knode.data;
64
- if (knodeData) {
65
- if (knodeData.routerView) {
66
- depth++;
67
- }
68
- if (knodeData.keepAlive && parent._inactive) {
69
- inactive = true;
70
- }
71
+ var knodeData = parent.$knode ? parent.$knode.data : {};
72
+ if (knodeData.routerView) {
73
+ depth++;
74
+ }
75
+ if (knodeData.keepAlive && parent._directInactive && parent._inactive) {
76
+ inactive = true;
71
77
  }
72
78
  parent = parent.$parent;
73
79
  }
@@ -75,17 +81,32 @@ var View = {
75
81
 
76
82
  // render previous view if the tree is inactive and kept-alive
77
83
  if (inactive) {
78
- return h(cache[name], data, children)
84
+ var cachedData = cache[name];
85
+ var cachedComponent = cachedData && cachedData.component;
86
+ if (cachedComponent) {
87
+ // #2301
88
+ // pass props
89
+ if (cachedData.configProps) {
90
+ fillPropsinData(cachedComponent, data, cachedData.route, cachedData.configProps);
91
+ }
92
+ return h(cachedComponent, data, children)
93
+ } else {
94
+ // render previous empty view
95
+ return h()
96
+ }
79
97
  }
80
98
 
81
99
  var matched = route.matched[depth];
82
- // render empty node if no matched route
83
- if (!matched) {
100
+ var component = matched && matched.components[name];
101
+
102
+ // render empty node if no matched route or no config component
103
+ if (!matched || !component) {
84
104
  cache[name] = null;
85
105
  return h()
86
106
  }
87
107
 
88
- var component = cache[name] = matched.components[name];
108
+ // cache component
109
+ cache[name] = { component: component };
89
110
 
90
111
  // attach instance registration hook
91
112
  // this will be called in the instance's injected lifecycle hooks
@@ -117,23 +138,35 @@ var View = {
117
138
  }
118
139
  };
119
140
 
120
- // resolve props
121
- var propsToPass = data.props = resolveProps(route, matched.props && matched.props[name]);
122
- if (propsToPass) {
123
- // clone to prevent mutation
124
- propsToPass = data.props = extend({}, propsToPass);
125
- // pass non-declared props as attrs
126
- var attrs = data.attrs = data.attrs || {};
127
- for (var key in propsToPass) {
128
- if (!component.props || !(key in component.props)) {
129
- attrs[key] = propsToPass[key];
130
- delete propsToPass[key];
131
- }
132
- }
141
+ var configProps = matched.props && matched.props[name];
142
+ // save route and configProps in cachce
143
+ if (configProps) {
144
+ extend(cache[name], {
145
+ route: route,
146
+ configProps: configProps
147
+ });
148
+ fillPropsinData(component, data, route, configProps);
133
149
  }
134
150
 
135
151
  return h(component, data, children)
136
152
  }
153
+ };
154
+
155
+ function fillPropsinData (component, data, route, configProps) {
156
+ // resolve props
157
+ var propsToPass = data.props = resolveProps(route, configProps);
158
+ if (propsToPass) {
159
+ // clone to prevent mutation
160
+ propsToPass = data.props = extend({}, propsToPass);
161
+ // pass non-declared props as attrs
162
+ var attrs = data.attrs = data.attrs || {};
163
+ for (var key in propsToPass) {
164
+ if (!component.props || !(key in component.props)) {
165
+ attrs[key] = propsToPass[key];
166
+ delete propsToPass[key];
167
+ }
168
+ }
169
+ }
137
170
  }
138
171
 
139
172
  function resolveProps (route, config) {
@@ -263,7 +296,7 @@ function createRoute (
263
296
  redirectedFrom,
264
297
  router
265
298
  ) {
266
- var stringifyQuery$$1 = router && router.options.stringifyQuery;
299
+ var stringifyQuery = router && router.options.stringifyQuery;
267
300
 
268
301
  var query = location.query || {};
269
302
  try {
@@ -277,11 +310,11 @@ function createRoute (
277
310
  hash: location.hash || '',
278
311
  query: query,
279
312
  params: location.params || {},
280
- fullPath: getFullPath(location, stringifyQuery$$1),
313
+ fullPath: getFullPath(location, stringifyQuery),
281
314
  matched: record ? formatMatch(record) : []
282
315
  };
283
316
  if (redirectedFrom) {
284
- route.redirectedFrom = getFullPath(redirectedFrom, stringifyQuery$$1);
317
+ route.redirectedFrom = getFullPath(redirectedFrom, stringifyQuery);
285
318
  }
286
319
  return Object.freeze(route)
287
320
  }
@@ -392,200 +425,6 @@ function queryIncludes (current, target) {
392
425
 
393
426
  /* */
394
427
 
395
- // work around weird flow bug
396
- var toTypes = [String, Object];
397
- var eventTypes = [String, Array];
398
-
399
- var Link = {
400
- name: 'RouterLink',
401
- props: {
402
- to: {
403
- type: toTypes,
404
- required: true
405
- },
406
- tag: {
407
- type: String,
408
- default: 'a'
409
- },
410
- exact: Boolean,
411
- append: Boolean,
412
- replace: Boolean,
413
- activeClass: String,
414
- exactActiveClass: String,
415
- event: {
416
- type: eventTypes,
417
- default: 'click'
418
- }
419
- },
420
- render: function render (h) {
421
- var this$1 = this;
422
-
423
- var router = this.$router;
424
- var current = this.$route;
425
- var ref = router.resolve(this.to, current, this.append);
426
- var location = ref.location;
427
- var route = ref.route;
428
- var href = ref.href;
429
-
430
- var classes = {};
431
- var globalActiveClass = router.options.linkActiveClass;
432
- var globalExactActiveClass = router.options.linkExactActiveClass;
433
- // Support global empty active class
434
- var activeClassFallback = globalActiveClass == null
435
- ? 'router-link-active'
436
- : globalActiveClass;
437
- var exactActiveClassFallback = globalExactActiveClass == null
438
- ? 'router-link-exact-active'
439
- : globalExactActiveClass;
440
- var activeClass = this.activeClass == null
441
- ? activeClassFallback
442
- : this.activeClass;
443
- var exactActiveClass = this.exactActiveClass == null
444
- ? exactActiveClassFallback
445
- : this.exactActiveClass;
446
- var compareTarget = location.path
447
- ? createRoute(null, location, null, router)
448
- : route;
449
-
450
- classes[exactActiveClass] = isSameRoute(current, compareTarget);
451
- classes[activeClass] = this.exact
452
- ? classes[exactActiveClass]
453
- : isIncludedRoute(current, compareTarget);
454
-
455
- var handler = function (e) {
456
- if (guardEvent(e)) {
457
- if (this$1.replace) {
458
- router.replace(location);
459
- } else {
460
- router.push(location);
461
- }
462
- }
463
- };
464
-
465
- var on = { click: guardEvent };
466
- if (Array.isArray(this.event)) {
467
- this.event.forEach(function (e) { on[e] = handler; });
468
- } else {
469
- on[this.event] = handler;
470
- }
471
-
472
- var data = {
473
- class: classes
474
- };
475
-
476
- if (this.tag === 'a') {
477
- data.on = on;
478
- data.attrs = { href: href };
479
- } else {
480
- // find the first <a> child and apply listener and href
481
- var a = findAnchor(this.$slots.default);
482
- if (a) {
483
- // in case the <a> is a static node
484
- a.isStatic = false;
485
- var aData = a.data = extend({}, a.data);
486
- aData.on = on;
487
- var aAttrs = a.data.attrs = extend({}, a.data.attrs);
488
- aAttrs.href = href;
489
- } else {
490
- // doesn't have <a> child, apply listener to self
491
- data.on = on;
492
- }
493
- }
494
-
495
- return h(this.tag, data, this.$slots.default)
496
- }
497
- }
498
-
499
- function guardEvent (e) {
500
- // don't redirect with control keys
501
- if (e.metaKey || e.altKey || e.ctrlKey || e.shiftKey) { return }
502
- // don't redirect when preventDefault called
503
- if (e.defaultPrevented) { return }
504
- // don't redirect on right click
505
- if (e.button !== undefined && e.button !== 0) { return }
506
- // don't redirect if `target="_blank"`
507
- if (e.currentTarget && e.currentTarget.getAttribute) {
508
- var target = e.currentTarget.getAttribute('target');
509
- if (/\b_blank\b/i.test(target)) { return }
510
- }
511
- // this may be a Weex event which doesn't have this method
512
- if (e.preventDefault) {
513
- e.preventDefault();
514
- }
515
- return true
516
- }
517
-
518
- function findAnchor (children) {
519
- if (children) {
520
- var child;
521
- for (var i = 0; i < children.length; i++) {
522
- child = children[i];
523
- if (child.tag === 'a') {
524
- return child
525
- }
526
- if (child.children && (child = findAnchor(child.children))) {
527
- return child
528
- }
529
- }
530
- }
531
- }
532
-
533
- var _Kdu;
534
-
535
- function install (Kdu) {
536
- if (install.installed && _Kdu === Kdu) { return }
537
- install.installed = true;
538
-
539
- _Kdu = Kdu;
540
-
541
- var isDef = function (v) { return v !== undefined; };
542
-
543
- var registerInstance = function (vm, callVal) {
544
- var i = vm.$options._parentKnode;
545
- if (isDef(i) && isDef(i = i.data) && isDef(i = i.registerRouteInstance)) {
546
- i(vm, callVal);
547
- }
548
- };
549
-
550
- Kdu.mixin({
551
- beforeCreate: function beforeCreate () {
552
- if (isDef(this.$options.router)) {
553
- this._routerRoot = this;
554
- this._router = this.$options.router;
555
- this._router.init(this);
556
- Kdu.util.defineReactive(this, '_route', this._router.history.current);
557
- } else {
558
- this._routerRoot = (this.$parent && this.$parent._routerRoot) || this;
559
- }
560
- registerInstance(this, this);
561
- },
562
- destroyed: function destroyed () {
563
- registerInstance(this);
564
- }
565
- });
566
-
567
- Object.defineProperty(Kdu.prototype, '$router', {
568
- get: function get () { return this._routerRoot._router }
569
- });
570
-
571
- Object.defineProperty(Kdu.prototype, '$route', {
572
- get: function get () { return this._routerRoot._route }
573
- });
574
-
575
- Kdu.component('RouterView', View);
576
- Kdu.component('RouterLink', Link);
577
-
578
- var strats = Kdu.config.optionMergeStrategies;
579
- // use the same hook merging strategy for route hooks
580
- strats.beforeRouteEnter = strats.beforeRouteLeave = strats.beforeRouteUpdate = strats.created;
581
- }
582
-
583
- /* */
584
-
585
- var inBrowser = typeof window !== 'undefined';
586
-
587
- /* */
588
-
589
428
  function resolvePath (
590
429
  relative,
591
430
  base,
@@ -1071,53 +910,361 @@ function pathToRegexp (path, keys, options) {
1071
910
  keys = [];
1072
911
  }
1073
912
 
1074
- options = options || {};
913
+ options = options || {};
914
+
915
+ if (path instanceof RegExp) {
916
+ return regexpToRegexp(path, /** @type {!Array} */ (keys))
917
+ }
918
+
919
+ if (isarray(path)) {
920
+ return arrayToRegexp(/** @type {!Array} */ (path), /** @type {!Array} */ (keys), options)
921
+ }
922
+
923
+ return stringToRegexp(/** @type {string} */ (path), /** @type {!Array} */ (keys), options)
924
+ }
925
+ pathToRegexp_1.parse = parse_1;
926
+ pathToRegexp_1.compile = compile_1;
927
+ pathToRegexp_1.tokensToFunction = tokensToFunction_1;
928
+ pathToRegexp_1.tokensToRegExp = tokensToRegExp_1;
929
+
930
+ /* */
931
+
932
+ // $flow-disable-line
933
+ var regexpCompileCache = Object.create(null);
934
+
935
+ function fillParams (
936
+ path,
937
+ params,
938
+ routeMsg
939
+ ) {
940
+ params = params || {};
941
+ try {
942
+ var filler =
943
+ regexpCompileCache[path] ||
944
+ (regexpCompileCache[path] = pathToRegexp_1.compile(path));
945
+
946
+ // Fix #2505 resolving asterisk routes { name: 'not-found', params: { pathMatch: '/not-found' }}
947
+ // and fix #3106 so that you can work with location descriptor object having params.pathMatch equal to empty string
948
+ if (typeof params.pathMatch === 'string') { params[0] = params.pathMatch; }
949
+
950
+ return filler(params, { pretty: true })
951
+ } catch (e) {
952
+ if (process.env.NODE_ENV !== 'production') {
953
+ // Fix #3072 no warn if `pathMatch` is string
954
+ warn(typeof params.pathMatch === 'string', ("missing param for " + routeMsg + ": " + (e.message)));
955
+ }
956
+ return ''
957
+ } finally {
958
+ // delete the 0 if it was added
959
+ delete params[0];
960
+ }
961
+ }
962
+
963
+ /* */
964
+
965
+ function normalizeLocation (
966
+ raw,
967
+ current,
968
+ append,
969
+ router
970
+ ) {
971
+ var next = typeof raw === 'string' ? { path: raw } : raw;
972
+ // named target
973
+ if (next._normalized) {
974
+ return next
975
+ } else if (next.name) {
976
+ next = extend({}, raw);
977
+ var params = next.params;
978
+ if (params && typeof params === 'object') {
979
+ next.params = extend({}, params);
980
+ }
981
+ return next
982
+ }
983
+
984
+ // relative params
985
+ if (!next.path && next.params && current) {
986
+ next = extend({}, next);
987
+ next._normalized = true;
988
+ var params$1 = extend(extend({}, current.params), next.params);
989
+ if (current.name) {
990
+ next.name = current.name;
991
+ next.params = params$1;
992
+ } else if (current.matched.length) {
993
+ var rawPath = current.matched[current.matched.length - 1].path;
994
+ next.path = fillParams(rawPath, params$1, ("path " + (current.path)));
995
+ } else if (process.env.NODE_ENV !== 'production') {
996
+ warn(false, "relative params navigation requires a current route.");
997
+ }
998
+ return next
999
+ }
1000
+
1001
+ var parsedPath = parsePath(next.path || '');
1002
+ var basePath = (current && current.path) || '/';
1003
+ var path = parsedPath.path
1004
+ ? resolvePath(parsedPath.path, basePath, append || next.append)
1005
+ : basePath;
1006
+
1007
+ var query = resolveQuery(
1008
+ parsedPath.query,
1009
+ next.query,
1010
+ router && router.options.parseQuery
1011
+ );
1012
+
1013
+ var hash = next.hash || parsedPath.hash;
1014
+ if (hash && hash.charAt(0) !== '#') {
1015
+ hash = "#" + hash;
1016
+ }
1017
+
1018
+ return {
1019
+ _normalized: true,
1020
+ path: path,
1021
+ query: query,
1022
+ hash: hash
1023
+ }
1024
+ }
1025
+
1026
+ /* */
1027
+
1028
+ // work around weird flow bug
1029
+ var toTypes = [String, Object];
1030
+ var eventTypes = [String, Array];
1031
+
1032
+ var noop = function () {};
1033
+
1034
+ var Link = {
1035
+ name: 'RouterLink',
1036
+ props: {
1037
+ to: {
1038
+ type: toTypes,
1039
+ required: true
1040
+ },
1041
+ tag: {
1042
+ type: String,
1043
+ default: 'a'
1044
+ },
1045
+ exact: Boolean,
1046
+ append: Boolean,
1047
+ replace: Boolean,
1048
+ activeClass: String,
1049
+ exactActiveClass: String,
1050
+ event: {
1051
+ type: eventTypes,
1052
+ default: 'click'
1053
+ }
1054
+ },
1055
+ render: function render (h) {
1056
+ var this$1 = this;
1057
+
1058
+ var router = this.$router;
1059
+ var current = this.$route;
1060
+ var ref = router.resolve(
1061
+ this.to,
1062
+ current,
1063
+ this.append
1064
+ );
1065
+ var location = ref.location;
1066
+ var route = ref.route;
1067
+ var href = ref.href;
1068
+
1069
+ var classes = {};
1070
+ var globalActiveClass = router.options.linkActiveClass;
1071
+ var globalExactActiveClass = router.options.linkExactActiveClass;
1072
+ // Support global empty active class
1073
+ var activeClassFallback =
1074
+ globalActiveClass == null ? 'router-link-active' : globalActiveClass;
1075
+ var exactActiveClassFallback =
1076
+ globalExactActiveClass == null
1077
+ ? 'router-link-exact-active'
1078
+ : globalExactActiveClass;
1079
+ var activeClass =
1080
+ this.activeClass == null ? activeClassFallback : this.activeClass;
1081
+ var exactActiveClass =
1082
+ this.exactActiveClass == null
1083
+ ? exactActiveClassFallback
1084
+ : this.exactActiveClass;
1085
+
1086
+ var compareTarget = route.redirectedFrom
1087
+ ? createRoute(null, normalizeLocation(route.redirectedFrom), null, router)
1088
+ : route;
1089
+
1090
+ classes[exactActiveClass] = isSameRoute(current, compareTarget);
1091
+ classes[activeClass] = this.exact
1092
+ ? classes[exactActiveClass]
1093
+ : isIncludedRoute(current, compareTarget);
1094
+
1095
+ var handler = function (e) {
1096
+ if (guardEvent(e)) {
1097
+ if (this$1.replace) {
1098
+ router.replace(location, noop);
1099
+ } else {
1100
+ router.push(location, noop);
1101
+ }
1102
+ }
1103
+ };
1104
+
1105
+ var on = { click: guardEvent };
1106
+ if (Array.isArray(this.event)) {
1107
+ this.event.forEach(function (e) {
1108
+ on[e] = handler;
1109
+ });
1110
+ } else {
1111
+ on[this.event] = handler;
1112
+ }
1113
+
1114
+ var data = { class: classes };
1115
+
1116
+ var scopedSlot =
1117
+ !this.$scopedSlots.$hasNormal &&
1118
+ this.$scopedSlots.default &&
1119
+ this.$scopedSlots.default({
1120
+ href: href,
1121
+ route: route,
1122
+ navigate: handler,
1123
+ isActive: classes[activeClass],
1124
+ isExactActive: classes[exactActiveClass]
1125
+ });
1126
+
1127
+ if (scopedSlot) {
1128
+ if (scopedSlot.length === 1) {
1129
+ return scopedSlot[0]
1130
+ } else if (scopedSlot.length > 1 || !scopedSlot.length) {
1131
+ if (process.env.NODE_ENV !== 'production') {
1132
+ warn(
1133
+ false,
1134
+ ("RouterLink with to=\"" + (this.to) + "\" is trying to use a scoped slot but it didn't provide exactly one child. Wrapping the content with a span element.")
1135
+ );
1136
+ }
1137
+ return scopedSlot.length === 0 ? h() : h('span', {}, scopedSlot)
1138
+ }
1139
+ }
1140
+
1141
+ if (this.tag === 'a') {
1142
+ data.on = on;
1143
+ data.attrs = { href: href };
1144
+ } else {
1145
+ // find the first <a> child and apply listener and href
1146
+ var a = findAnchor(this.$slots.default);
1147
+ if (a) {
1148
+ // in case the <a> is a static node
1149
+ a.isStatic = false;
1150
+ var aData = (a.data = extend({}, a.data));
1151
+ aData.on = aData.on || {};
1152
+ // transform existing events in both objects into arrays so we can push later
1153
+ for (var event in aData.on) {
1154
+ var handler$1 = aData.on[event];
1155
+ if (event in on) {
1156
+ aData.on[event] = Array.isArray(handler$1) ? handler$1 : [handler$1];
1157
+ }
1158
+ }
1159
+ // append new listeners for router-link
1160
+ for (var event$1 in on) {
1161
+ if (event$1 in aData.on) {
1162
+ // on[event] is always a function
1163
+ aData.on[event$1].push(on[event$1]);
1164
+ } else {
1165
+ aData.on[event$1] = handler;
1166
+ }
1167
+ }
1168
+
1169
+ var aAttrs = (a.data.attrs = extend({}, a.data.attrs));
1170
+ aAttrs.href = href;
1171
+ } else {
1172
+ // doesn't have <a> child, apply listener to self
1173
+ data.on = on;
1174
+ }
1175
+ }
1176
+
1177
+ return h(this.tag, data, this.$slots.default)
1178
+ }
1179
+ };
1180
+
1181
+ function guardEvent (e) {
1182
+ // don't redirect with control keys
1183
+ if (e.metaKey || e.altKey || e.ctrlKey || e.shiftKey) { return }
1184
+ // don't redirect when preventDefault called
1185
+ if (e.defaultPrevented) { return }
1186
+ // don't redirect on right click
1187
+ if (e.button !== undefined && e.button !== 0) { return }
1188
+ // don't redirect if `target="_blank"`
1189
+ if (e.currentTarget && e.currentTarget.getAttribute) {
1190
+ var target = e.currentTarget.getAttribute('target');
1191
+ if (/\b_blank\b/i.test(target)) { return }
1192
+ }
1193
+ // this may be a Weex event which doesn't have this method
1194
+ if (e.preventDefault) {
1195
+ e.preventDefault();
1196
+ }
1197
+ return true
1198
+ }
1199
+
1200
+ function findAnchor (children) {
1201
+ if (children) {
1202
+ var child;
1203
+ for (var i = 0; i < children.length; i++) {
1204
+ child = children[i];
1205
+ if (child.tag === 'a') {
1206
+ return child
1207
+ }
1208
+ if (child.children && (child = findAnchor(child.children))) {
1209
+ return child
1210
+ }
1211
+ }
1212
+ }
1213
+ }
1214
+
1215
+ var _Kdu;
1216
+
1217
+ function install (Kdu) {
1218
+ if (install.installed && _Kdu === Kdu) { return }
1219
+ install.installed = true;
1220
+
1221
+ _Kdu = Kdu;
1222
+
1223
+ var isDef = function (v) { return v !== undefined; };
1224
+
1225
+ var registerInstance = function (vm, callVal) {
1226
+ var i = vm.$options._parentKnode;
1227
+ if (isDef(i) && isDef(i = i.data) && isDef(i = i.registerRouteInstance)) {
1228
+ i(vm, callVal);
1229
+ }
1230
+ };
1231
+
1232
+ Kdu.mixin({
1233
+ beforeCreate: function beforeCreate () {
1234
+ if (isDef(this.$options.router)) {
1235
+ this._routerRoot = this;
1236
+ this._router = this.$options.router;
1237
+ this._router.init(this);
1238
+ Kdu.util.defineReactive(this, '_route', this._router.history.current);
1239
+ } else {
1240
+ this._routerRoot = (this.$parent && this.$parent._routerRoot) || this;
1241
+ }
1242
+ registerInstance(this, this);
1243
+ },
1244
+ destroyed: function destroyed () {
1245
+ registerInstance(this);
1246
+ }
1247
+ });
1248
+
1249
+ Object.defineProperty(Kdu.prototype, '$router', {
1250
+ get: function get () { return this._routerRoot._router }
1251
+ });
1075
1252
 
1076
- if (path instanceof RegExp) {
1077
- return regexpToRegexp(path, /** @type {!Array} */ (keys))
1078
- }
1253
+ Object.defineProperty(Kdu.prototype, '$route', {
1254
+ get: function get () { return this._routerRoot._route }
1255
+ });
1079
1256
 
1080
- if (isarray(path)) {
1081
- return arrayToRegexp(/** @type {!Array} */ (path), /** @type {!Array} */ (keys), options)
1082
- }
1257
+ Kdu.component('RouterView', View);
1258
+ Kdu.component('RouterLink', Link);
1083
1259
 
1084
- return stringToRegexp(/** @type {string} */ (path), /** @type {!Array} */ (keys), options)
1260
+ var strats = Kdu.config.optionMergeStrategies;
1261
+ // use the same hook merging strategy for route hooks
1262
+ strats.beforeRouteEnter = strats.beforeRouteLeave = strats.beforeRouteUpdate = strats.created;
1085
1263
  }
1086
- pathToRegexp_1.parse = parse_1;
1087
- pathToRegexp_1.compile = compile_1;
1088
- pathToRegexp_1.tokensToFunction = tokensToFunction_1;
1089
- pathToRegexp_1.tokensToRegExp = tokensToRegExp_1;
1090
1264
 
1091
1265
  /* */
1092
1266
 
1093
- // $flow-disable-line
1094
- var regexpCompileCache = Object.create(null);
1095
-
1096
- function fillParams (
1097
- path,
1098
- params,
1099
- routeMsg
1100
- ) {
1101
- params = params || {};
1102
- try {
1103
- var filler =
1104
- regexpCompileCache[path] ||
1105
- (regexpCompileCache[path] = pathToRegexp_1.compile(path));
1106
-
1107
- // Fix #2505 resolving asterisk routes { name: 'not-found', params: { pathMatch: '/not-found' }}
1108
- if (params.pathMatch) { params[0] = params.pathMatch; }
1109
-
1110
- return filler(params, { pretty: true })
1111
- } catch (e) {
1112
- if (process.env.NODE_ENV !== 'production') {
1113
- warn(false, ("missing param for " + routeMsg + ": " + (e.message)));
1114
- }
1115
- return ''
1116
- } finally {
1117
- // delete the 0 if it was added
1118
- delete params[0];
1119
- }
1120
- }
1267
+ var inBrowser = typeof window !== 'undefined';
1121
1268
 
1122
1269
  /* */
1123
1270
 
@@ -1147,6 +1294,18 @@ function createRouteMap (
1147
1294
  }
1148
1295
  }
1149
1296
 
1297
+ if (process.env.NODE_ENV === 'development') {
1298
+ // warn if routes do not include leading slashes
1299
+ var found = pathList
1300
+ // check for missing leading slash
1301
+ .filter(function (path) { return path && path.charAt(0) !== '*' && path.charAt(0) !== '/'; });
1302
+
1303
+ if (found.length > 0) {
1304
+ var pathNames = found.map(function (path) { return ("- " + path); }).join('\n');
1305
+ warn(false, ("Non-nested routes must include a leading slash character. Fix the following routes: \n" + pathNames));
1306
+ }
1307
+ }
1308
+
1150
1309
  return {
1151
1310
  pathList: pathList,
1152
1311
  pathMap: pathMap,
@@ -1168,17 +1327,15 @@ function addRouteRecord (
1168
1327
  assert(path != null, "\"path\" is required in a route configuration.");
1169
1328
  assert(
1170
1329
  typeof route.component !== 'string',
1171
- "route config \"component\" for path: " + (String(path || name)) + " cannot be a " +
1172
- "string id. Use an actual component instead."
1330
+ "route config \"component\" for path: " + (String(
1331
+ path || name
1332
+ )) + " cannot be a " + "string id. Use an actual component instead."
1173
1333
  );
1174
1334
  }
1175
1335
 
1176
- var pathToRegexpOptions = route.pathToRegexpOptions || {};
1177
- var normalizedPath = normalizePath(
1178
- path,
1179
- parent,
1180
- pathToRegexpOptions.strict
1181
- );
1336
+ var pathToRegexpOptions =
1337
+ route.pathToRegexpOptions || {};
1338
+ var normalizedPath = normalizePath(path, parent, pathToRegexpOptions.strict);
1182
1339
 
1183
1340
  if (typeof route.caseSensitive === 'boolean') {
1184
1341
  pathToRegexpOptions.sensitive = route.caseSensitive;
@@ -1195,11 +1352,12 @@ function addRouteRecord (
1195
1352
  redirect: route.redirect,
1196
1353
  beforeEnter: route.beforeEnter,
1197
1354
  meta: route.meta || {},
1198
- props: route.props == null
1199
- ? {}
1200
- : route.components
1201
- ? route.props
1202
- : { default: route.props }
1355
+ props:
1356
+ route.props == null
1357
+ ? {}
1358
+ : route.components
1359
+ ? route.props
1360
+ : { default: route.props }
1203
1361
  };
1204
1362
 
1205
1363
  if (route.children) {
@@ -1207,14 +1365,18 @@ function addRouteRecord (
1207
1365
  // If users navigate to this route by name, the default child will
1208
1366
  // not be rendered (GH Issue #629)
1209
1367
  if (process.env.NODE_ENV !== 'production') {
1210
- if (route.name && !route.redirect && route.children.some(function (child) { return /^\/?$/.test(child.path); })) {
1368
+ if (
1369
+ route.name &&
1370
+ !route.redirect &&
1371
+ route.children.some(function (child) { return /^\/?$/.test(child.path); })
1372
+ ) {
1211
1373
  warn(
1212
1374
  false,
1213
1375
  "Named Route '" + (route.name) + "' has a default child route. " +
1214
- "When navigating to this named route (:to=\"{name: '" + (route.name) + "'\"), " +
1215
- "the default child route will not be rendered. Remove the name from " +
1216
- "this route and use the name of the default child route for named " +
1217
- "links instead."
1376
+ "When navigating to this named route (:to=\"{name: '" + (route.name) + "'\"), " +
1377
+ "the default child route will not be rendered. Remove the name from " +
1378
+ "this route and use the name of the default child route for named " +
1379
+ "links instead."
1218
1380
  );
1219
1381
  }
1220
1382
  }
@@ -1226,12 +1388,24 @@ function addRouteRecord (
1226
1388
  });
1227
1389
  }
1228
1390
 
1391
+ if (!pathMap[record.path]) {
1392
+ pathList.push(record.path);
1393
+ pathMap[record.path] = record;
1394
+ }
1395
+
1229
1396
  if (route.alias !== undefined) {
1230
- var aliases = Array.isArray(route.alias)
1231
- ? route.alias
1232
- : [route.alias];
1397
+ var aliases = Array.isArray(route.alias) ? route.alias : [route.alias];
1398
+ for (var i = 0; i < aliases.length; ++i) {
1399
+ var alias = aliases[i];
1400
+ if (process.env.NODE_ENV !== 'production' && alias === path) {
1401
+ warn(
1402
+ false,
1403
+ ("Found an alias with the same value as the path: \"" + path + "\". You have to remove that alias. It will be ignored in development.")
1404
+ );
1405
+ // skip in dev to make it work
1406
+ continue
1407
+ }
1233
1408
 
1234
- aliases.forEach(function (alias) {
1235
1409
  var aliasRoute = {
1236
1410
  path: alias,
1237
1411
  children: route.children
@@ -1244,12 +1418,7 @@ function addRouteRecord (
1244
1418
  parent,
1245
1419
  record.path || '/' // matchAs
1246
1420
  );
1247
- });
1248
- }
1249
-
1250
- if (!pathMap[record.path]) {
1251
- pathList.push(record.path);
1252
- pathMap[record.path] = record;
1421
+ }
1253
1422
  }
1254
1423
 
1255
1424
  if (name) {
@@ -1259,25 +1428,35 @@ function addRouteRecord (
1259
1428
  warn(
1260
1429
  false,
1261
1430
  "Duplicate named routes definition: " +
1262
- "{ name: \"" + name + "\", path: \"" + (record.path) + "\" }"
1431
+ "{ name: \"" + name + "\", path: \"" + (record.path) + "\" }"
1263
1432
  );
1264
1433
  }
1265
1434
  }
1266
1435
  }
1267
1436
 
1268
- function compileRouteRegex (path, pathToRegexpOptions) {
1437
+ function compileRouteRegex (
1438
+ path,
1439
+ pathToRegexpOptions
1440
+ ) {
1269
1441
  var regex = pathToRegexp_1(path, [], pathToRegexpOptions);
1270
1442
  if (process.env.NODE_ENV !== 'production') {
1271
1443
  var keys = Object.create(null);
1272
1444
  regex.keys.forEach(function (key) {
1273
- warn(!keys[key.name], ("Duplicate param keys in route with path: \"" + path + "\""));
1445
+ warn(
1446
+ !keys[key.name],
1447
+ ("Duplicate param keys in route with path: \"" + path + "\"")
1448
+ );
1274
1449
  keys[key.name] = true;
1275
1450
  });
1276
1451
  }
1277
1452
  return regex
1278
1453
  }
1279
1454
 
1280
- function normalizePath (path, parent, strict) {
1455
+ function normalizePath (
1456
+ path,
1457
+ parent,
1458
+ strict
1459
+ ) {
1281
1460
  if (!strict) { path = path.replace(/\/$/, ''); }
1282
1461
  if (path[0] === '/') { return path }
1283
1462
  if (parent == null) { return path }
@@ -1286,64 +1465,6 @@ function normalizePath (path, parent, strict) {
1286
1465
 
1287
1466
  /* */
1288
1467
 
1289
- function normalizeLocation (
1290
- raw,
1291
- current,
1292
- append,
1293
- router
1294
- ) {
1295
- var next = typeof raw === 'string' ? { path: raw } : raw;
1296
- // named target
1297
- if (next._normalized) {
1298
- return next
1299
- } else if (next.name) {
1300
- return extend({}, raw)
1301
- }
1302
-
1303
- // relative params
1304
- if (!next.path && next.params && current) {
1305
- next = extend({}, next);
1306
- next._normalized = true;
1307
- var params = extend(extend({}, current.params), next.params);
1308
- if (current.name) {
1309
- next.name = current.name;
1310
- next.params = params;
1311
- } else if (current.matched.length) {
1312
- var rawPath = current.matched[current.matched.length - 1].path;
1313
- next.path = fillParams(rawPath, params, ("path " + (current.path)));
1314
- } else if (process.env.NODE_ENV !== 'production') {
1315
- warn(false, "relative params navigation requires a current route.");
1316
- }
1317
- return next
1318
- }
1319
-
1320
- var parsedPath = parsePath(next.path || '');
1321
- var basePath = (current && current.path) || '/';
1322
- var path = parsedPath.path
1323
- ? resolvePath(parsedPath.path, basePath, append || next.append)
1324
- : basePath;
1325
-
1326
- var query = resolveQuery(
1327
- parsedPath.query,
1328
- next.query,
1329
- router && router.options.parseQuery
1330
- );
1331
-
1332
- var hash = next.hash || parsedPath.hash;
1333
- if (hash && hash.charAt(0) !== '#') {
1334
- hash = "#" + hash;
1335
- }
1336
-
1337
- return {
1338
- _normalized: true,
1339
- path: path,
1340
- query: query,
1341
- hash: hash
1342
- }
1343
- }
1344
-
1345
- /* */
1346
-
1347
1468
 
1348
1469
 
1349
1470
  function createMatcher (
@@ -1540,6 +1661,28 @@ function resolveRecordPath (path, record) {
1540
1661
 
1541
1662
  /* */
1542
1663
 
1664
+ // use User Timing api (if present) for more accurate key precision
1665
+ var Time =
1666
+ inBrowser && window.performance && window.performance.now
1667
+ ? window.performance
1668
+ : Date;
1669
+
1670
+ function genStateKey () {
1671
+ return Time.now().toFixed(3)
1672
+ }
1673
+
1674
+ var _key = genStateKey();
1675
+
1676
+ function getStateKey () {
1677
+ return _key
1678
+ }
1679
+
1680
+ function setStateKey (key) {
1681
+ return (_key = key)
1682
+ }
1683
+
1684
+ /* */
1685
+
1543
1686
  var positionStore = Object.create(null);
1544
1687
 
1545
1688
  function setupScroll () {
@@ -1550,7 +1693,10 @@ function setupScroll () {
1550
1693
  // location.host contains the port and location.hostname doesn't
1551
1694
  var protocolAndPath = window.location.protocol + '//' + window.location.host;
1552
1695
  var absolutePath = window.location.href.replace(protocolAndPath, '');
1553
- window.history.replaceState({ key: getStateKey() }, '', absolutePath);
1696
+ // preserve existing history state as it could be overriden by the user
1697
+ var stateCopy = extend({}, window.history.state);
1698
+ stateCopy.key = getStateKey();
1699
+ window.history.replaceState(stateCopy, '', absolutePath);
1554
1700
  window.addEventListener('popstate', function (e) {
1555
1701
  saveScrollPosition();
1556
1702
  if (e.state && e.state.key) {
@@ -1581,20 +1727,27 @@ function handleScroll (
1581
1727
  // wait until re-render finishes before scrolling
1582
1728
  router.app.$nextTick(function () {
1583
1729
  var position = getScrollPosition();
1584
- var shouldScroll = behavior.call(router, to, from, isPop ? position : null);
1730
+ var shouldScroll = behavior.call(
1731
+ router,
1732
+ to,
1733
+ from,
1734
+ isPop ? position : null
1735
+ );
1585
1736
 
1586
1737
  if (!shouldScroll) {
1587
1738
  return
1588
1739
  }
1589
1740
 
1590
1741
  if (typeof shouldScroll.then === 'function') {
1591
- shouldScroll.then(function (shouldScroll) {
1592
- scrollToPosition((shouldScroll), position);
1593
- }).catch(function (err) {
1594
- if (process.env.NODE_ENV !== 'production') {
1595
- assert(false, err.toString());
1596
- }
1597
- });
1742
+ shouldScroll
1743
+ .then(function (shouldScroll) {
1744
+ scrollToPosition((shouldScroll), position);
1745
+ })
1746
+ .catch(function (err) {
1747
+ if (process.env.NODE_ENV !== 'production') {
1748
+ assert(false, err.toString());
1749
+ }
1750
+ });
1598
1751
  } else {
1599
1752
  scrollToPosition(shouldScroll, position);
1600
1753
  }
@@ -1650,12 +1803,22 @@ function isNumber (v) {
1650
1803
  return typeof v === 'number'
1651
1804
  }
1652
1805
 
1806
+ var hashStartsWithNumberRE = /^#\d/;
1807
+
1653
1808
  function scrollToPosition (shouldScroll, position) {
1654
1809
  var isObject = typeof shouldScroll === 'object';
1655
1810
  if (isObject && typeof shouldScroll.selector === 'string') {
1656
- var el = document.querySelector(shouldScroll.selector);
1811
+ // getElementById would still fail if the selector contains a more complicated query like #main[data-attr]
1812
+ // but at the same time, it doesn't make much sense to select an element with an id and an extra selector
1813
+ var el = hashStartsWithNumberRE.test(shouldScroll.selector) // $flow-disable-line
1814
+ ? document.getElementById(shouldScroll.selector.slice(1)) // $flow-disable-line
1815
+ : document.querySelector(shouldScroll.selector);
1816
+
1657
1817
  if (el) {
1658
- var offset = shouldScroll.offset && typeof shouldScroll.offset === 'object' ? shouldScroll.offset : {};
1818
+ var offset =
1819
+ shouldScroll.offset && typeof shouldScroll.offset === 'object'
1820
+ ? shouldScroll.offset
1821
+ : {};
1659
1822
  offset = normalizeOffset(offset);
1660
1823
  position = getElementPosition(el, offset);
1661
1824
  } else if (isValidPosition(shouldScroll)) {
@@ -1672,39 +1835,22 @@ function scrollToPosition (shouldScroll, position) {
1672
1835
 
1673
1836
  /* */
1674
1837
 
1675
- var supportsPushState = inBrowser && (function () {
1676
- var ua = window.navigator.userAgent;
1677
-
1678
- if (
1679
- (ua.indexOf('Android 2.') !== -1 || ua.indexOf('Android 4.0') !== -1) &&
1680
- ua.indexOf('Mobile Safari') !== -1 &&
1681
- ua.indexOf('Chrome') === -1 &&
1682
- ua.indexOf('Windows Phone') === -1
1683
- ) {
1684
- return false
1685
- }
1686
-
1687
- return window.history && 'pushState' in window.history
1688
- })();
1689
-
1690
- // use User Timing api (if present) for more accurate key precision
1691
- var Time = inBrowser && window.performance && window.performance.now
1692
- ? window.performance
1693
- : Date;
1694
-
1695
- var _key = genKey();
1696
-
1697
- function genKey () {
1698
- return Time.now().toFixed(3)
1699
- }
1700
-
1701
- function getStateKey () {
1702
- return _key
1703
- }
1838
+ var supportsPushState =
1839
+ inBrowser &&
1840
+ (function () {
1841
+ var ua = window.navigator.userAgent;
1842
+
1843
+ if (
1844
+ (ua.indexOf('Android 2.') !== -1 || ua.indexOf('Android 4.0') !== -1) &&
1845
+ ua.indexOf('Mobile Safari') !== -1 &&
1846
+ ua.indexOf('Chrome') === -1 &&
1847
+ ua.indexOf('Windows Phone') === -1
1848
+ ) {
1849
+ return false
1850
+ }
1704
1851
 
1705
- function setStateKey (key) {
1706
- _key = key;
1707
- }
1852
+ return window.history && 'pushState' in window.history
1853
+ })();
1708
1854
 
1709
1855
  function pushState (url, replace) {
1710
1856
  saveScrollPosition();
@@ -1713,10 +1859,12 @@ function pushState (url, replace) {
1713
1859
  var history = window.history;
1714
1860
  try {
1715
1861
  if (replace) {
1716
- history.replaceState({ key: _key }, '', url);
1862
+ // preserve existing history state as it could be overriden by the user
1863
+ var stateCopy = extend({}, history.state);
1864
+ stateCopy.key = getStateKey();
1865
+ history.replaceState(stateCopy, '', url);
1717
1866
  } else {
1718
- _key = genKey();
1719
- history.pushState({ key: _key }, '', url);
1867
+ history.pushState({ key: setStateKey(genStateKey()) }, '', url);
1720
1868
  }
1721
1869
  } catch (e) {
1722
1870
  window.location[replace ? 'replace' : 'assign'](url);
@@ -1855,6 +2003,33 @@ function once (fn) {
1855
2003
  }
1856
2004
  }
1857
2005
 
2006
+ var NavigationDuplicated = /*@__PURE__*/(function (Error) {
2007
+ function NavigationDuplicated (normalizedLocation) {
2008
+ Error.call(this);
2009
+ this.name = this._name = 'NavigationDuplicated';
2010
+ // passing the message to super() doesn't seem to work in the transpiled version
2011
+ this.message = "Navigating to current location (\"" + (normalizedLocation.fullPath) + "\") is not allowed";
2012
+ // add a stack property so services like Sentry can correctly display it
2013
+ Object.defineProperty(this, 'stack', {
2014
+ value: new Error().stack,
2015
+ writable: true,
2016
+ configurable: true
2017
+ });
2018
+ // we could also have used
2019
+ // Error.captureStackTrace(this, this.constructor)
2020
+ // but it only exists on node and chrome
2021
+ }
2022
+
2023
+ if ( Error ) NavigationDuplicated.__proto__ = Error;
2024
+ NavigationDuplicated.prototype = Object.create( Error && Error.prototype );
2025
+ NavigationDuplicated.prototype.constructor = NavigationDuplicated;
2026
+
2027
+ return NavigationDuplicated;
2028
+ }(Error));
2029
+
2030
+ // support IE9
2031
+ NavigationDuplicated._name = 'NavigationDuplicated';
2032
+
1858
2033
  /* */
1859
2034
 
1860
2035
  var History = function History (router, base) {
@@ -1888,29 +2063,41 @@ History.prototype.onError = function onError (errorCb) {
1888
2063
  this.errorCbs.push(errorCb);
1889
2064
  };
1890
2065
 
1891
- History.prototype.transitionTo = function transitionTo (location, onComplete, onAbort) {
2066
+ History.prototype.transitionTo = function transitionTo (
2067
+ location,
2068
+ onComplete,
2069
+ onAbort
2070
+ ) {
1892
2071
  var this$1 = this;
1893
2072
 
1894
2073
  var route = this.router.match(location, this.current);
1895
- this.confirmTransition(route, function () {
1896
- this$1.updateRoute(route);
1897
- onComplete && onComplete(route);
1898
- this$1.ensureURL();
2074
+ this.confirmTransition(
2075
+ route,
2076
+ function () {
2077
+ this$1.updateRoute(route);
2078
+ onComplete && onComplete(route);
2079
+ this$1.ensureURL();
1899
2080
 
1900
- // fire ready cbs once
1901
- if (!this$1.ready) {
1902
- this$1.ready = true;
1903
- this$1.readyCbs.forEach(function (cb) { cb(route); });
1904
- }
1905
- }, function (err) {
1906
- if (onAbort) {
1907
- onAbort(err);
1908
- }
1909
- if (err && !this$1.ready) {
1910
- this$1.ready = true;
1911
- this$1.readyErrorCbs.forEach(function (cb) { cb(err); });
2081
+ // fire ready cbs once
2082
+ if (!this$1.ready) {
2083
+ this$1.ready = true;
2084
+ this$1.readyCbs.forEach(function (cb) {
2085
+ cb(route);
2086
+ });
2087
+ }
2088
+ },
2089
+ function (err) {
2090
+ if (onAbort) {
2091
+ onAbort(err);
2092
+ }
2093
+ if (err && !this$1.ready) {
2094
+ this$1.ready = true;
2095
+ this$1.readyErrorCbs.forEach(function (cb) {
2096
+ cb(err);
2097
+ });
2098
+ }
1912
2099
  }
1913
- });
2100
+ );
1914
2101
  };
1915
2102
 
1916
2103
  History.prototype.confirmTransition = function confirmTransition (route, onComplete, onAbort) {
@@ -1918,9 +2105,14 @@ History.prototype.confirmTransition = function confirmTransition (route, onCompl
1918
2105
 
1919
2106
  var current = this.current;
1920
2107
  var abort = function (err) {
1921
- if (isError(err)) {
2108
+ // When the user navigates through history through back/forward buttons
2109
+ // we do not want to throw the error. We only throw it if directly calling
2110
+ // push/replace. That's why it's not included in isError
2111
+ if (!isExtendedError(NavigationDuplicated, err) && isError(err)) {
1922
2112
  if (this$1.errorCbs.length) {
1923
- this$1.errorCbs.forEach(function (cb) { cb(err); });
2113
+ this$1.errorCbs.forEach(function (cb) {
2114
+ cb(err);
2115
+ });
1924
2116
  } else {
1925
2117
  warn(false, 'uncaught error during route navigation:');
1926
2118
  console.error(err);
@@ -1934,10 +2126,13 @@ History.prototype.confirmTransition = function confirmTransition (route, onCompl
1934
2126
  route.matched.length === current.matched.length
1935
2127
  ) {
1936
2128
  this.ensureURL();
1937
- return abort()
2129
+ return abort(new NavigationDuplicated(route))
1938
2130
  }
1939
2131
 
1940
- var ref = resolveQueue(this.current.matched, route.matched);
2132
+ var ref = resolveQueue(
2133
+ this.current.matched,
2134
+ route.matched
2135
+ );
1941
2136
  var updated = ref.updated;
1942
2137
  var deactivated = ref.deactivated;
1943
2138
  var activated = ref.activated;
@@ -1968,10 +2163,8 @@ History.prototype.confirmTransition = function confirmTransition (route, onCompl
1968
2163
  abort(to);
1969
2164
  } else if (
1970
2165
  typeof to === 'string' ||
1971
- (typeof to === 'object' && (
1972
- typeof to.path === 'string' ||
1973
- typeof to.name === 'string'
1974
- ))
2166
+ (typeof to === 'object' &&
2167
+ (typeof to.path === 'string' || typeof to.name === 'string'))
1975
2168
  ) {
1976
2169
  // next('/') or next({ path: '/' }) -> redirect
1977
2170
  abort();
@@ -2005,7 +2198,9 @@ History.prototype.confirmTransition = function confirmTransition (route, onCompl
2005
2198
  onComplete(route);
2006
2199
  if (this$1.router.app) {
2007
2200
  this$1.router.app.$nextTick(function () {
2008
- postEnterCbs.forEach(function (cb) { cb(); });
2201
+ postEnterCbs.forEach(function (cb) {
2202
+ cb();
2203
+ });
2009
2204
  });
2010
2205
  }
2011
2206
  });
@@ -2108,9 +2303,13 @@ function extractEnterGuards (
2108
2303
  cbs,
2109
2304
  isValid
2110
2305
  ) {
2111
- return extractGuards(activated, 'beforeRouteEnter', function (guard, _, match, key) {
2112
- return bindEnterGuard(guard, match, key, cbs, isValid)
2113
- })
2306
+ return extractGuards(
2307
+ activated,
2308
+ 'beforeRouteEnter',
2309
+ function (guard, _, match, key) {
2310
+ return bindEnterGuard(guard, match, key, cbs, isValid)
2311
+ }
2312
+ )
2114
2313
  }
2115
2314
 
2116
2315
  function bindEnterGuard (
@@ -2157,11 +2356,11 @@ function poll (
2157
2356
 
2158
2357
  /* */
2159
2358
 
2160
- var HTML5History = /*@__PURE__*/(function (History$$1) {
2359
+ var HTML5History = /*@__PURE__*/(function (History) {
2161
2360
  function HTML5History (router, base) {
2162
2361
  var this$1 = this;
2163
2362
 
2164
- History$$1.call(this, router, base);
2363
+ History.call(this, router, base);
2165
2364
 
2166
2365
  var expectScroll = router.options.scrollBehavior;
2167
2366
  var supportsScroll = supportsPushState && expectScroll;
@@ -2189,8 +2388,8 @@ var HTML5History = /*@__PURE__*/(function (History$$1) {
2189
2388
  });
2190
2389
  }
2191
2390
 
2192
- if ( History$$1 ) HTML5History.__proto__ = History$$1;
2193
- HTML5History.prototype = Object.create( History$$1 && History$$1.prototype );
2391
+ if ( History ) HTML5History.__proto__ = History;
2392
+ HTML5History.prototype = Object.create( History && History.prototype );
2194
2393
  HTML5History.prototype.constructor = HTML5History;
2195
2394
 
2196
2395
  HTML5History.prototype.go = function go (n) {
@@ -2245,9 +2444,9 @@ function getLocation (base) {
2245
2444
 
2246
2445
  /* */
2247
2446
 
2248
- var HashHistory = /*@__PURE__*/(function (History$$1) {
2447
+ var HashHistory = /*@__PURE__*/(function (History) {
2249
2448
  function HashHistory (router, base, fallback) {
2250
- History$$1.call(this, router, base);
2449
+ History.call(this, router, base);
2251
2450
  // check history fallback deeplinking
2252
2451
  if (fallback && checkFallback(this.base)) {
2253
2452
  return
@@ -2255,8 +2454,8 @@ var HashHistory = /*@__PURE__*/(function (History$$1) {
2255
2454
  ensureSlash();
2256
2455
  }
2257
2456
 
2258
- if ( History$$1 ) HashHistory.__proto__ = History$$1;
2259
- HashHistory.prototype = Object.create( History$$1 && History$$1.prototype );
2457
+ if ( History ) HashHistory.__proto__ = History;
2458
+ HashHistory.prototype = Object.create( History && History.prototype );
2260
2459
  HashHistory.prototype.constructor = HashHistory;
2261
2460
 
2262
2461
  // this is delayed until the app mounts
@@ -2272,20 +2471,23 @@ var HashHistory = /*@__PURE__*/(function (History$$1) {
2272
2471
  setupScroll();
2273
2472
  }
2274
2473
 
2275
- window.addEventListener(supportsPushState ? 'popstate' : 'hashchange', function () {
2276
- var current = this$1.current;
2277
- if (!ensureSlash()) {
2278
- return
2279
- }
2280
- this$1.transitionTo(getHash(), function (route) {
2281
- if (supportsScroll) {
2282
- handleScroll(this$1.router, route, current, true);
2283
- }
2284
- if (!supportsPushState) {
2285
- replaceHash(route.fullPath);
2474
+ window.addEventListener(
2475
+ supportsPushState ? 'popstate' : 'hashchange',
2476
+ function () {
2477
+ var current = this$1.current;
2478
+ if (!ensureSlash()) {
2479
+ return
2286
2480
  }
2287
- });
2288
- });
2481
+ this$1.transitionTo(getHash(), function (route) {
2482
+ if (supportsScroll) {
2483
+ handleScroll(this$1.router, route, current, true);
2484
+ }
2485
+ if (!supportsPushState) {
2486
+ replaceHash(route.fullPath);
2487
+ }
2488
+ });
2489
+ }
2490
+ );
2289
2491
  };
2290
2492
 
2291
2493
  HashHistory.prototype.push = function push (location, onComplete, onAbort) {
@@ -2293,11 +2495,15 @@ var HashHistory = /*@__PURE__*/(function (History$$1) {
2293
2495
 
2294
2496
  var ref = this;
2295
2497
  var fromRoute = ref.current;
2296
- this.transitionTo(location, function (route) {
2297
- pushHash(route.fullPath);
2298
- handleScroll(this$1.router, route, fromRoute, false);
2299
- onComplete && onComplete(route);
2300
- }, onAbort);
2498
+ this.transitionTo(
2499
+ location,
2500
+ function (route) {
2501
+ pushHash(route.fullPath);
2502
+ handleScroll(this$1.router, route, fromRoute, false);
2503
+ onComplete && onComplete(route);
2504
+ },
2505
+ onAbort
2506
+ );
2301
2507
  };
2302
2508
 
2303
2509
  HashHistory.prototype.replace = function replace (location, onComplete, onAbort) {
@@ -2305,11 +2511,15 @@ var HashHistory = /*@__PURE__*/(function (History$$1) {
2305
2511
 
2306
2512
  var ref = this;
2307
2513
  var fromRoute = ref.current;
2308
- this.transitionTo(location, function (route) {
2309
- replaceHash(route.fullPath);
2310
- handleScroll(this$1.router, route, fromRoute, false);
2311
- onComplete && onComplete(route);
2312
- }, onAbort);
2514
+ this.transitionTo(
2515
+ location,
2516
+ function (route) {
2517
+ replaceHash(route.fullPath);
2518
+ handleScroll(this$1.router, route, fromRoute, false);
2519
+ onComplete && onComplete(route);
2520
+ },
2521
+ onAbort
2522
+ );
2313
2523
  };
2314
2524
 
2315
2525
  HashHistory.prototype.go = function go (n) {
@@ -2333,9 +2543,7 @@ var HashHistory = /*@__PURE__*/(function (History$$1) {
2333
2543
  function checkFallback (base) {
2334
2544
  var location = getLocation(base);
2335
2545
  if (!/^\/#/.test(location)) {
2336
- window.location.replace(
2337
- cleanPath(base + '/#' + location)
2338
- );
2546
+ window.location.replace(cleanPath(base + '/#' + location));
2339
2547
  return true
2340
2548
  }
2341
2549
  }
@@ -2363,10 +2571,11 @@ function getHash () {
2363
2571
  var searchIndex = href.indexOf('?');
2364
2572
  if (searchIndex < 0) {
2365
2573
  var hashIndex = href.indexOf('#');
2366
- if (hashIndex > -1) { href = decodeURI(href.slice(0, hashIndex)) + href.slice(hashIndex); }
2367
- else { href = decodeURI(href); }
2574
+ if (hashIndex > -1) {
2575
+ href = decodeURI(href.slice(0, hashIndex)) + href.slice(hashIndex);
2576
+ } else { href = decodeURI(href); }
2368
2577
  } else {
2369
- if (searchIndex > -1) { href = decodeURI(href.slice(0, searchIndex)) + href.slice(searchIndex); }
2578
+ href = decodeURI(href.slice(0, searchIndex)) + href.slice(searchIndex);
2370
2579
  }
2371
2580
 
2372
2581
  return href
@@ -2397,34 +2606,42 @@ function replaceHash (path) {
2397
2606
 
2398
2607
  /* */
2399
2608
 
2400
- var AbstractHistory = /*@__PURE__*/(function (History$$1) {
2609
+ var AbstractHistory = /*@__PURE__*/(function (History) {
2401
2610
  function AbstractHistory (router, base) {
2402
- History$$1.call(this, router, base);
2611
+ History.call(this, router, base);
2403
2612
  this.stack = [];
2404
2613
  this.index = -1;
2405
2614
  }
2406
2615
 
2407
- if ( History$$1 ) AbstractHistory.__proto__ = History$$1;
2408
- AbstractHistory.prototype = Object.create( History$$1 && History$$1.prototype );
2616
+ if ( History ) AbstractHistory.__proto__ = History;
2617
+ AbstractHistory.prototype = Object.create( History && History.prototype );
2409
2618
  AbstractHistory.prototype.constructor = AbstractHistory;
2410
2619
 
2411
2620
  AbstractHistory.prototype.push = function push (location, onComplete, onAbort) {
2412
2621
  var this$1 = this;
2413
2622
 
2414
- this.transitionTo(location, function (route) {
2415
- this$1.stack = this$1.stack.slice(0, this$1.index + 1).concat(route);
2416
- this$1.index++;
2417
- onComplete && onComplete(route);
2418
- }, onAbort);
2623
+ this.transitionTo(
2624
+ location,
2625
+ function (route) {
2626
+ this$1.stack = this$1.stack.slice(0, this$1.index + 1).concat(route);
2627
+ this$1.index++;
2628
+ onComplete && onComplete(route);
2629
+ },
2630
+ onAbort
2631
+ );
2419
2632
  };
2420
2633
 
2421
2634
  AbstractHistory.prototype.replace = function replace (location, onComplete, onAbort) {
2422
2635
  var this$1 = this;
2423
2636
 
2424
- this.transitionTo(location, function (route) {
2425
- this$1.stack = this$1.stack.slice(0, this$1.index).concat(route);
2426
- onComplete && onComplete(route);
2427
- }, onAbort);
2637
+ this.transitionTo(
2638
+ location,
2639
+ function (route) {
2640
+ this$1.stack = this$1.stack.slice(0, this$1.index).concat(route);
2641
+ onComplete && onComplete(route);
2642
+ },
2643
+ onAbort
2644
+ );
2428
2645
  };
2429
2646
 
2430
2647
  AbstractHistory.prototype.go = function go (n) {
@@ -2435,10 +2652,18 @@ var AbstractHistory = /*@__PURE__*/(function (History$$1) {
2435
2652
  return
2436
2653
  }
2437
2654
  var route = this.stack[targetIndex];
2438
- this.confirmTransition(route, function () {
2439
- this$1.index = targetIndex;
2440
- this$1.updateRoute(route);
2441
- });
2655
+ this.confirmTransition(
2656
+ route,
2657
+ function () {
2658
+ this$1.index = targetIndex;
2659
+ this$1.updateRoute(route);
2660
+ },
2661
+ function (err) {
2662
+ if (isExtendedError(NavigationDuplicated, err)) {
2663
+ this$1.index = targetIndex;
2664
+ }
2665
+ }
2666
+ );
2442
2667
  };
2443
2668
 
2444
2669
  AbstractHistory.prototype.getCurrentLocation = function getCurrentLocation () {
@@ -2581,11 +2806,29 @@ KduRouter.prototype.onError = function onError (errorCb) {
2581
2806
  };
2582
2807
 
2583
2808
  KduRouter.prototype.push = function push (location, onComplete, onAbort) {
2584
- this.history.push(location, onComplete, onAbort);
2809
+ var this$1 = this;
2810
+
2811
+ // $flow-disable-line
2812
+ if (!onComplete && !onAbort && typeof Promise !== 'undefined') {
2813
+ return new Promise(function (resolve, reject) {
2814
+ this$1.history.push(location, resolve, reject);
2815
+ })
2816
+ } else {
2817
+ this.history.push(location, onComplete, onAbort);
2818
+ }
2585
2819
  };
2586
2820
 
2587
2821
  KduRouter.prototype.replace = function replace (location, onComplete, onAbort) {
2588
- this.history.replace(location, onComplete, onAbort);
2822
+ var this$1 = this;
2823
+
2824
+ // $flow-disable-line
2825
+ if (!onComplete && !onAbort && typeof Promise !== 'undefined') {
2826
+ return new Promise(function (resolve, reject) {
2827
+ this$1.history.replace(location, resolve, reject);
2828
+ })
2829
+ } else {
2830
+ this.history.replace(location, onComplete, onAbort);
2831
+ }
2589
2832
  };
2590
2833
 
2591
2834
  KduRouter.prototype.go = function go (n) {
@@ -2665,7 +2908,7 @@ function createHref (base, fullPath, mode) {
2665
2908
  }
2666
2909
 
2667
2910
  KduRouter.install = install;
2668
- KduRouter.version = '3.0.7';
2911
+ KduRouter.version = '3.1.7';
2669
2912
 
2670
2913
  if (inBrowser && window.Kdu) {
2671
2914
  window.Kdu.use(KduRouter);