kdu-router 2.7.0 → 3.0.1

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 v2.7.0
2
+ * kdu-router v3.0.1
3
3
  * (c) 2022 NKDuy
4
4
  * @license MIT
5
5
  */
@@ -50,7 +50,7 @@ var View = {
50
50
  var depth = 0;
51
51
  var inactive = false;
52
52
  while (parent && parent._routerRoot !== parent) {
53
- if (parent.$vnode && parent.$vnode.data.routerView) {
53
+ if (parent.$knode && parent.$knode.data.routerView) {
54
54
  depth++;
55
55
  }
56
56
  if (parent._inactive) {
@@ -87,14 +87,26 @@ var View = {
87
87
  }
88
88
  }
89
89
 
90
- // also regiseter instance in prepatch hook
90
+ // also register instance in prepatch hook
91
91
  // in case the same component instance is reused across different routes
92
- ;(data.hook || (data.hook = {})).prepatch = function (_, vnode) {
93
- matched.instances[name] = vnode.componentInstance;
92
+ ;(data.hook || (data.hook = {})).prepatch = function (_, knode) {
93
+ matched.instances[name] = knode.componentInstance;
94
94
  };
95
95
 
96
96
  // resolve props
97
- data.props = resolveProps(route, matched.props && matched.props[name]);
97
+ var propsToPass = data.props = resolveProps(route, matched.props && matched.props[name]);
98
+ if (propsToPass) {
99
+ // clone to prevent mutation
100
+ propsToPass = data.props = extend({}, propsToPass);
101
+ // pass non-declared props as attrs
102
+ var attrs = data.attrs = data.attrs || {};
103
+ for (var key in propsToPass) {
104
+ if (!component.props || !(key in component.props)) {
105
+ attrs[key] = propsToPass[key];
106
+ delete propsToPass[key];
107
+ }
108
+ }
109
+ }
98
110
 
99
111
  return h(component, data, children)
100
112
  }
@@ -121,6 +133,13 @@ function resolveProps (route, config) {
121
133
  }
122
134
  }
123
135
 
136
+ function extend (to, from) {
137
+ for (var key in from) {
138
+ to[key] = from[key];
139
+ }
140
+ return to
141
+ }
142
+
124
143
  /* */
125
144
 
126
145
  var encodeReserveRE = /[!'()*]/g;
@@ -152,8 +171,7 @@ function resolveQuery (
152
171
  parsedQuery = {};
153
172
  }
154
173
  for (var key in extraQuery) {
155
- var val = extraQuery[key];
156
- parsedQuery[key] = Array.isArray(val) ? val.slice() : val;
174
+ parsedQuery[key] = extraQuery[key];
157
175
  }
158
176
  return parsedQuery
159
177
  }
@@ -230,12 +248,18 @@ function createRoute (
230
248
  router
231
249
  ) {
232
250
  var stringifyQuery$$1 = router && router.options.stringifyQuery;
251
+
252
+ var query = location.query || {};
253
+ try {
254
+ query = clone(query);
255
+ } catch (e) {}
256
+
233
257
  var route = {
234
258
  name: location.name || (record && record.name),
235
259
  meta: (record && record.meta) || {},
236
260
  path: location.path || '/',
237
261
  hash: location.hash || '',
238
- query: location.query || {},
262
+ query: query,
239
263
  params: location.params || {},
240
264
  fullPath: getFullPath(location, stringifyQuery$$1),
241
265
  matched: record ? formatMatch(record) : []
@@ -246,6 +270,20 @@ function createRoute (
246
270
  return Object.freeze(route)
247
271
  }
248
272
 
273
+ function clone (value) {
274
+ if (Array.isArray(value)) {
275
+ return value.map(clone)
276
+ } else if (value && typeof value === 'object') {
277
+ var res = {};
278
+ for (var key in value) {
279
+ res[key] = clone(value[key]);
280
+ }
281
+ return res
282
+ } else {
283
+ return value
284
+ }
285
+ }
286
+
249
287
  // the starting route that represents the initial state
250
288
  var START = createRoute(null, {
251
289
  path: '/'
@@ -299,6 +337,8 @@ function isObjectEqual (a, b) {
299
337
  if ( a === void 0 ) a = {};
300
338
  if ( b === void 0 ) b = {};
301
339
 
340
+ // handle null value #1566
341
+ if (!a || !b) { return a === b }
302
342
  var aKeys = Object.keys(a);
303
343
  var bKeys = Object.keys(b);
304
344
  if (aKeys.length !== bKeys.length) {
@@ -478,7 +518,7 @@ function findAnchor (children) {
478
518
  var _Kdu;
479
519
 
480
520
  function install (Kdu) {
481
- if (install.installed) { return }
521
+ if (install.installed && _Kdu === Kdu) { return }
482
522
  install.installed = true;
483
523
 
484
524
  _Kdu = Kdu;
@@ -486,7 +526,7 @@ function install (Kdu) {
486
526
  var isDef = function (v) { return v !== undefined; };
487
527
 
488
528
  var registerInstance = function (vm, callVal) {
489
- var i = vm.$options._parentVnode;
529
+ var i = vm.$options._parentKnode;
490
530
  if (isDef(i) && isDef(i = i.data) && isDef(i = i.registerRouteInstance)) {
491
531
  i(vm, callVal);
492
532
  }
@@ -600,14 +640,14 @@ function cleanPath (path) {
600
640
  return path.replace(/\/\//g, '/')
601
641
  }
602
642
 
603
- var index$1 = Array.isArray || function (arr) {
643
+ var isarray = Array.isArray || function (arr) {
604
644
  return Object.prototype.toString.call(arr) == '[object Array]';
605
645
  };
606
646
 
607
647
  /**
608
648
  * Expose `pathToRegexp`.
609
649
  */
610
- var index = pathToRegexp;
650
+ var pathToRegexp_1 = pathToRegexp;
611
651
  var parse_1 = parse;
612
652
  var compile_1 = compile;
613
653
  var tokensToFunction_1 = tokensToFunction;
@@ -712,7 +752,7 @@ function parse (str, options) {
712
752
  * @return {!function(Object=, Object=)}
713
753
  */
714
754
  function compile (str, options) {
715
- return tokensToFunction(parse(str, options))
755
+ return tokensToFunction(parse(str, options), options)
716
756
  }
717
757
 
718
758
  /**
@@ -742,14 +782,14 @@ function encodeAsterisk (str) {
742
782
  /**
743
783
  * Expose a method for transforming tokens into the path function.
744
784
  */
745
- function tokensToFunction (tokens) {
785
+ function tokensToFunction (tokens, options) {
746
786
  // Compile all the tokens into regexps.
747
787
  var matches = new Array(tokens.length);
748
788
 
749
789
  // Compile all the patterns before compilation.
750
790
  for (var i = 0; i < tokens.length; i++) {
751
791
  if (typeof tokens[i] === 'object') {
752
- matches[i] = new RegExp('^(?:' + tokens[i].pattern + ')$');
792
+ matches[i] = new RegExp('^(?:' + tokens[i].pattern + ')$', flags(options));
753
793
  }
754
794
  }
755
795
 
@@ -784,7 +824,7 @@ function tokensToFunction (tokens) {
784
824
  }
785
825
  }
786
826
 
787
- if (index$1(value)) {
827
+ if (isarray(value)) {
788
828
  if (!token.repeat) {
789
829
  throw new TypeError('Expected "' + token.name + '" to not repeat, but received `' + JSON.stringify(value) + '`')
790
830
  }
@@ -862,7 +902,7 @@ function attachKeys (re, keys) {
862
902
  * @return {string}
863
903
  */
864
904
  function flags (options) {
865
- return options.sensitive ? '' : 'i'
905
+ return options && options.sensitive ? '' : 'i'
866
906
  }
867
907
 
868
908
  /**
@@ -935,7 +975,7 @@ function stringToRegexp (path, keys, options) {
935
975
  * @return {!RegExp}
936
976
  */
937
977
  function tokensToRegExp (tokens, keys, options) {
938
- if (!index$1(keys)) {
978
+ if (!isarray(keys)) {
939
979
  options = /** @type {!Object} */ (keys || options);
940
980
  keys = [];
941
981
  }
@@ -1011,7 +1051,7 @@ function tokensToRegExp (tokens, keys, options) {
1011
1051
  * @return {!RegExp}
1012
1052
  */
1013
1053
  function pathToRegexp (path, keys, options) {
1014
- if (!index$1(keys)) {
1054
+ if (!isarray(keys)) {
1015
1055
  options = /** @type {!Object} */ (keys || options);
1016
1056
  keys = [];
1017
1057
  }
@@ -1022,20 +1062,21 @@ function pathToRegexp (path, keys, options) {
1022
1062
  return regexpToRegexp(path, /** @type {!Array} */ (keys))
1023
1063
  }
1024
1064
 
1025
- if (index$1(path)) {
1065
+ if (isarray(path)) {
1026
1066
  return arrayToRegexp(/** @type {!Array} */ (path), /** @type {!Array} */ (keys), options)
1027
1067
  }
1028
1068
 
1029
1069
  return stringToRegexp(/** @type {string} */ (path), /** @type {!Array} */ (keys), options)
1030
1070
  }
1031
1071
 
1032
- index.parse = parse_1;
1033
- index.compile = compile_1;
1034
- index.tokensToFunction = tokensToFunction_1;
1035
- index.tokensToRegExp = tokensToRegExp_1;
1072
+ pathToRegexp_1.parse = parse_1;
1073
+ pathToRegexp_1.compile = compile_1;
1074
+ pathToRegexp_1.tokensToFunction = tokensToFunction_1;
1075
+ pathToRegexp_1.tokensToRegExp = tokensToRegExp_1;
1036
1076
 
1037
1077
  /* */
1038
1078
 
1079
+ // $flow-disable-line
1039
1080
  var regexpCompileCache = Object.create(null);
1040
1081
 
1041
1082
  function fillParams (
@@ -1046,7 +1087,7 @@ function fillParams (
1046
1087
  try {
1047
1088
  var filler =
1048
1089
  regexpCompileCache[path] ||
1049
- (regexpCompileCache[path] = index.compile(path));
1090
+ (regexpCompileCache[path] = pathToRegexp_1.compile(path));
1050
1091
  return filler(params || {}, { pretty: true })
1051
1092
  } catch (e) {
1052
1093
  if (process.env.NODE_ENV !== 'production') {
@@ -1066,7 +1107,9 @@ function createRouteMap (
1066
1107
  ) {
1067
1108
  // the path list is used to control path matching priority
1068
1109
  var pathList = oldPathList || [];
1110
+ // $flow-disable-line
1069
1111
  var pathMap = oldPathMap || Object.create(null);
1112
+ // $flow-disable-line
1070
1113
  var nameMap = oldNameMap || Object.create(null);
1071
1114
 
1072
1115
  routes.forEach(function (route) {
@@ -1108,8 +1151,12 @@ function addRouteRecord (
1108
1151
  );
1109
1152
  }
1110
1153
 
1111
- var normalizedPath = normalizePath(path, parent);
1112
1154
  var pathToRegexpOptions = route.pathToRegexpOptions || {};
1155
+ var normalizedPath = normalizePath(
1156
+ path,
1157
+ parent,
1158
+ pathToRegexpOptions.strict
1159
+ );
1113
1160
 
1114
1161
  if (typeof route.caseSensitive === 'boolean') {
1115
1162
  pathToRegexpOptions.sensitive = route.caseSensitive;
@@ -1197,9 +1244,9 @@ function addRouteRecord (
1197
1244
  }
1198
1245
 
1199
1246
  function compileRouteRegex (path, pathToRegexpOptions) {
1200
- var regex = index(path, [], pathToRegexpOptions);
1247
+ var regex = pathToRegexp_1(path, [], pathToRegexpOptions);
1201
1248
  if (process.env.NODE_ENV !== 'production') {
1202
- var keys = {};
1249
+ var keys = Object.create(null);
1203
1250
  regex.keys.forEach(function (key) {
1204
1251
  warn(!keys[key.name], ("Duplicate param keys in route with path: \"" + path + "\""));
1205
1252
  keys[key.name] = true;
@@ -1208,8 +1255,8 @@ function compileRouteRegex (path, pathToRegexpOptions) {
1208
1255
  return regex
1209
1256
  }
1210
1257
 
1211
- function normalizePath (path, parent) {
1212
- path = path.replace(/\/$/, '');
1258
+ function normalizePath (path, parent, strict) {
1259
+ if (!strict) { path = path.replace(/\/$/, ''); }
1213
1260
  if (path[0] === '/') { return path }
1214
1261
  if (parent == null) { return path }
1215
1262
  return cleanPath(((parent.path) + "/" + path))
@@ -1481,6 +1528,8 @@ function resolveRecordPath (path, record) {
1481
1528
  var positionStore = Object.create(null);
1482
1529
 
1483
1530
  function setupScroll () {
1531
+ // Fix for #1585 for Firefox
1532
+ window.history.replaceState({ key: getStateKey() }, '');
1484
1533
  window.addEventListener('popstate', function (e) {
1485
1534
  saveScrollPosition();
1486
1535
  if (e.state && e.state.key) {
@@ -1512,25 +1561,21 @@ function handleScroll (
1512
1561
  router.app.$nextTick(function () {
1513
1562
  var position = getScrollPosition();
1514
1563
  var shouldScroll = behavior(to, from, isPop ? position : null);
1564
+
1515
1565
  if (!shouldScroll) {
1516
1566
  return
1517
1567
  }
1518
- var isObject = typeof shouldScroll === 'object';
1519
- if (isObject && typeof shouldScroll.selector === 'string') {
1520
- var el = document.querySelector(shouldScroll.selector);
1521
- if (el) {
1522
- var offset = shouldScroll.offset && typeof shouldScroll.offset === 'object' ? shouldScroll.offset : {};
1523
- offset = normalizeOffset(offset);
1524
- position = getElementPosition(el, offset);
1525
- } else if (isValidPosition(shouldScroll)) {
1526
- position = normalizePosition(shouldScroll);
1527
- }
1528
- } else if (isObject && isValidPosition(shouldScroll)) {
1529
- position = normalizePosition(shouldScroll);
1530
- }
1531
1568
 
1532
- if (position) {
1533
- window.scrollTo(position.x, position.y);
1569
+ if (typeof shouldScroll.then === 'function') {
1570
+ shouldScroll.then(function (shouldScroll) {
1571
+ scrollToPosition((shouldScroll), position);
1572
+ }).catch(function (err) {
1573
+ if (process.env.NODE_ENV !== 'production') {
1574
+ assert(false, err.toString());
1575
+ }
1576
+ });
1577
+ } else {
1578
+ scrollToPosition(shouldScroll, position);
1534
1579
  }
1535
1580
  });
1536
1581
  }
@@ -1584,6 +1629,26 @@ function isNumber (v) {
1584
1629
  return typeof v === 'number'
1585
1630
  }
1586
1631
 
1632
+ function scrollToPosition (shouldScroll, position) {
1633
+ var isObject = typeof shouldScroll === 'object';
1634
+ if (isObject && typeof shouldScroll.selector === 'string') {
1635
+ var el = document.querySelector(shouldScroll.selector);
1636
+ if (el) {
1637
+ var offset = shouldScroll.offset && typeof shouldScroll.offset === 'object' ? shouldScroll.offset : {};
1638
+ offset = normalizeOffset(offset);
1639
+ position = getElementPosition(el, offset);
1640
+ } else if (isValidPosition(shouldScroll)) {
1641
+ position = normalizePosition(shouldScroll);
1642
+ }
1643
+ } else if (isObject && isValidPosition(shouldScroll)) {
1644
+ position = normalizePosition(shouldScroll);
1645
+ }
1646
+
1647
+ if (position) {
1648
+ window.scrollTo(position.x, position.y);
1649
+ }
1650
+ }
1651
+
1587
1652
  /* */
1588
1653
 
1589
1654
  var supportsPushState = inBrowser && (function () {
@@ -1679,7 +1744,7 @@ function resolveAsyncComponents (matched) {
1679
1744
  pending++;
1680
1745
 
1681
1746
  var resolve = once(function (resolvedDef) {
1682
- if (resolvedDef.__esModule && resolvedDef.default) {
1747
+ if (isESModule(resolvedDef)) {
1683
1748
  resolvedDef = resolvedDef.default;
1684
1749
  }
1685
1750
  // save resolved on async factory in case it's used elsewhere
@@ -1714,7 +1779,7 @@ function resolveAsyncComponents (matched) {
1714
1779
  if (typeof res.then === 'function') {
1715
1780
  res.then(resolve, reject);
1716
1781
  } else {
1717
- // new syntax in Kdu
1782
+ // new syntax in Kdu 2.3
1718
1783
  var comp = res.component;
1719
1784
  if (comp && typeof comp.then === 'function') {
1720
1785
  comp.then(resolve, reject);
@@ -1745,6 +1810,14 @@ function flatten (arr) {
1745
1810
  return Array.prototype.concat.apply([], arr)
1746
1811
  }
1747
1812
 
1813
+ var hasSymbol =
1814
+ typeof Symbol === 'function' &&
1815
+ typeof Symbol.toStringTag === 'symbol';
1816
+
1817
+ function isESModule (obj) {
1818
+ return obj.__esModule || (hasSymbol && obj[Symbol.toStringTag] === 'Module')
1819
+ }
1820
+
1748
1821
  // in Webpack 2, require.ensure now also returns a Promise
1749
1822
  // so the resolve/reject functions may get called an extra time
1750
1823
  // if the user uses an arrow function shorthand that happens to
@@ -2073,9 +2146,18 @@ var HTML5History = (function (History$$1) {
2073
2146
  setupScroll();
2074
2147
  }
2075
2148
 
2149
+ var initLocation = getLocation(this.base);
2076
2150
  window.addEventListener('popstate', function (e) {
2077
2151
  var current = this$1.current;
2078
- this$1.transitionTo(getLocation(this$1.base), function (route) {
2152
+
2153
+ // Avoiding first `popstate` event dispatched in some browsers but first
2154
+ // history route not updated since async guard at the same time.
2155
+ var location = getLocation(this$1.base);
2156
+ if (this$1.current === START && location === initLocation) {
2157
+ return
2158
+ }
2159
+
2160
+ this$1.transitionTo(location, function (route) {
2079
2161
  if (expectScroll) {
2080
2162
  handleScroll(router, route, current, true);
2081
2163
  }
@@ -2159,26 +2241,50 @@ var HashHistory = (function (History$$1) {
2159
2241
  HashHistory.prototype.setupListeners = function setupListeners () {
2160
2242
  var this$1 = this;
2161
2243
 
2162
- window.addEventListener('hashchange', function () {
2244
+ var router = this.router;
2245
+ var expectScroll = router.options.scrollBehavior;
2246
+ var supportsScroll = supportsPushState && expectScroll;
2247
+
2248
+ if (supportsScroll) {
2249
+ setupScroll();
2250
+ }
2251
+
2252
+ window.addEventListener(supportsPushState ? 'popstate' : 'hashchange', function () {
2253
+ var current = this$1.current;
2163
2254
  if (!ensureSlash()) {
2164
2255
  return
2165
2256
  }
2166
2257
  this$1.transitionTo(getHash(), function (route) {
2167
- replaceHash(route.fullPath);
2258
+ if (supportsScroll) {
2259
+ handleScroll(this$1.router, route, current, true);
2260
+ }
2261
+ if (!supportsPushState) {
2262
+ replaceHash(route.fullPath);
2263
+ }
2168
2264
  });
2169
2265
  });
2170
2266
  };
2171
2267
 
2172
2268
  HashHistory.prototype.push = function push (location, onComplete, onAbort) {
2269
+ var this$1 = this;
2270
+
2271
+ var ref = this;
2272
+ var fromRoute = ref.current;
2173
2273
  this.transitionTo(location, function (route) {
2174
2274
  pushHash(route.fullPath);
2275
+ handleScroll(this$1.router, route, fromRoute, false);
2175
2276
  onComplete && onComplete(route);
2176
2277
  }, onAbort);
2177
2278
  };
2178
2279
 
2179
2280
  HashHistory.prototype.replace = function replace (location, onComplete, onAbort) {
2281
+ var this$1 = this;
2282
+
2283
+ var ref = this;
2284
+ var fromRoute = ref.current;
2180
2285
  this.transitionTo(location, function (route) {
2181
2286
  replaceHash(route.fullPath);
2287
+ handleScroll(this$1.router, route, fromRoute, false);
2182
2288
  onComplete && onComplete(route);
2183
2289
  }, onAbort);
2184
2290
  };
@@ -2228,15 +2334,27 @@ function getHash () {
2228
2334
  return index === -1 ? '' : href.slice(index + 1)
2229
2335
  }
2230
2336
 
2337
+ function getUrl (path) {
2338
+ var href = window.location.href;
2339
+ var i = href.indexOf('#');
2340
+ var base = i >= 0 ? href.slice(0, i) : href;
2341
+ return (base + "#" + path)
2342
+ }
2343
+
2231
2344
  function pushHash (path) {
2232
- window.location.hash = path;
2345
+ if (supportsPushState) {
2346
+ pushState(getUrl(path));
2347
+ } else {
2348
+ window.location.hash = path;
2349
+ }
2233
2350
  }
2234
2351
 
2235
2352
  function replaceHash (path) {
2236
- var href = window.location.href;
2237
- var i = href.indexOf('#');
2238
- var base = i >= 0 ? href.slice(0, i) : href;
2239
- window.location.replace((base + "#" + path));
2353
+ if (supportsPushState) {
2354
+ replaceState(getUrl(path));
2355
+ } else {
2356
+ window.location.replace(getUrl(path));
2357
+ }
2240
2358
  }
2241
2359
 
2242
2360
  /* */
@@ -2338,7 +2456,7 @@ var KduRouter = function KduRouter (options) {
2338
2456
  }
2339
2457
  };
2340
2458
 
2341
- var prototypeAccessors = { currentRoute: {} };
2459
+ var prototypeAccessors = { currentRoute: { configurable: true } };
2342
2460
 
2343
2461
  KduRouter.prototype.match = function match (
2344
2462
  raw,
@@ -2496,7 +2614,7 @@ function createHref (base, fullPath, mode) {
2496
2614
  }
2497
2615
 
2498
2616
  KduRouter.install = install;
2499
- KduRouter.version = '2.7.0';
2617
+ KduRouter.version = '3.0.1';
2500
2618
 
2501
2619
  if (inBrowser && window.Kdu) {
2502
2620
  window.Kdu.use(KduRouter);