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.
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2022 NKDuy
3
+ Copyright (c) 2021-present NKDuy
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -1,10 +1,8 @@
1
1
  # kdu-router
2
2
 
3
- > This is kdu-router 2.0 which works only with Kdu 2.0..
4
-
5
3
  ### Introduction
6
4
 
7
- `kdu-router` is the official router for Kdu.js. It deeply integrates with Kdu.js core to make building Single Page Applications with Kdu.js a breeze. Features include:
5
+ `kdu-router` is the official router for [Kdu.js](http://kdu-js.web.app). It deeply integrates with Kdu.js core to make building Single Page Applications with Kdu.js a breeze. Features include:
8
6
 
9
7
  - Nested route/view mapping
10
8
  - Modular, component-based router configuration
@@ -15,31 +13,10 @@
15
13
  - HTML5 history mode or hash mode, with auto-fallback in IE9
16
14
  - Customizable Scroll Behavior
17
15
 
18
- Get started with the [documentation](http://khanhduy1407.github.io/kdu-router), or play with the [examples](https://github.com/khanhduy1407/kdu-router/tree/dev/examples) (see how to run them below).
19
-
20
- ### Development Setup
21
-
22
- ``` bash
23
- # install deps
24
- npm install
25
-
26
- # build dist files
27
- npm run build
28
-
29
- # serve examples at localhost:8080
30
- npm run dev
31
-
32
- # lint & run all tests
33
- npm test
34
-
35
- # serve docs at localhost:4000 (requires global gitbook-cli)
36
- npm run docs
37
- ```
38
-
39
16
  ## License
40
17
 
41
18
  [MIT](http://opensource.org/licenses/MIT)
42
19
 
43
- Copyright (c) 2022 NKDuy
20
+ Copyright (c) 2021-present NKDuy
44
21
 
45
22
 
@@ -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
  */
@@ -52,7 +52,7 @@ var View = {
52
52
  var depth = 0;
53
53
  var inactive = false;
54
54
  while (parent && parent._routerRoot !== parent) {
55
- if (parent.$vnode && parent.$vnode.data.routerView) {
55
+ if (parent.$knode && parent.$knode.data.routerView) {
56
56
  depth++;
57
57
  }
58
58
  if (parent._inactive) {
@@ -89,14 +89,26 @@ var View = {
89
89
  }
90
90
  }
91
91
 
92
- // also regiseter instance in prepatch hook
92
+ // also register instance in prepatch hook
93
93
  // in case the same component instance is reused across different routes
94
- ;(data.hook || (data.hook = {})).prepatch = function (_, vnode) {
95
- matched.instances[name] = vnode.componentInstance;
94
+ ;(data.hook || (data.hook = {})).prepatch = function (_, knode) {
95
+ matched.instances[name] = knode.componentInstance;
96
96
  };
97
97
 
98
98
  // resolve props
99
- data.props = resolveProps(route, matched.props && matched.props[name]);
99
+ var propsToPass = data.props = resolveProps(route, matched.props && matched.props[name]);
100
+ if (propsToPass) {
101
+ // clone to prevent mutation
102
+ propsToPass = data.props = extend({}, propsToPass);
103
+ // pass non-declared props as attrs
104
+ var attrs = data.attrs = data.attrs || {};
105
+ for (var key in propsToPass) {
106
+ if (!component.props || !(key in component.props)) {
107
+ attrs[key] = propsToPass[key];
108
+ delete propsToPass[key];
109
+ }
110
+ }
111
+ }
100
112
 
101
113
  return h(component, data, children)
102
114
  }
@@ -123,6 +135,13 @@ function resolveProps (route, config) {
123
135
  }
124
136
  }
125
137
 
138
+ function extend (to, from) {
139
+ for (var key in from) {
140
+ to[key] = from[key];
141
+ }
142
+ return to
143
+ }
144
+
126
145
  /* */
127
146
 
128
147
  var encodeReserveRE = /[!'()*]/g;
@@ -154,8 +173,7 @@ function resolveQuery (
154
173
  parsedQuery = {};
155
174
  }
156
175
  for (var key in extraQuery) {
157
- var val = extraQuery[key];
158
- parsedQuery[key] = Array.isArray(val) ? val.slice() : val;
176
+ parsedQuery[key] = extraQuery[key];
159
177
  }
160
178
  return parsedQuery
161
179
  }
@@ -232,12 +250,18 @@ function createRoute (
232
250
  router
233
251
  ) {
234
252
  var stringifyQuery$$1 = router && router.options.stringifyQuery;
253
+
254
+ var query = location.query || {};
255
+ try {
256
+ query = clone(query);
257
+ } catch (e) {}
258
+
235
259
  var route = {
236
260
  name: location.name || (record && record.name),
237
261
  meta: (record && record.meta) || {},
238
262
  path: location.path || '/',
239
263
  hash: location.hash || '',
240
- query: location.query || {},
264
+ query: query,
241
265
  params: location.params || {},
242
266
  fullPath: getFullPath(location, stringifyQuery$$1),
243
267
  matched: record ? formatMatch(record) : []
@@ -248,6 +272,20 @@ function createRoute (
248
272
  return Object.freeze(route)
249
273
  }
250
274
 
275
+ function clone (value) {
276
+ if (Array.isArray(value)) {
277
+ return value.map(clone)
278
+ } else if (value && typeof value === 'object') {
279
+ var res = {};
280
+ for (var key in value) {
281
+ res[key] = clone(value[key]);
282
+ }
283
+ return res
284
+ } else {
285
+ return value
286
+ }
287
+ }
288
+
251
289
  // the starting route that represents the initial state
252
290
  var START = createRoute(null, {
253
291
  path: '/'
@@ -301,6 +339,8 @@ function isObjectEqual (a, b) {
301
339
  if ( a === void 0 ) a = {};
302
340
  if ( b === void 0 ) b = {};
303
341
 
342
+ // handle null value #1566
343
+ if (!a || !b) { return a === b }
304
344
  var aKeys = Object.keys(a);
305
345
  var bKeys = Object.keys(b);
306
346
  if (aKeys.length !== bKeys.length) {
@@ -480,7 +520,7 @@ function findAnchor (children) {
480
520
  var _Kdu;
481
521
 
482
522
  function install (Kdu) {
483
- if (install.installed) { return }
523
+ if (install.installed && _Kdu === Kdu) { return }
484
524
  install.installed = true;
485
525
 
486
526
  _Kdu = Kdu;
@@ -488,7 +528,7 @@ function install (Kdu) {
488
528
  var isDef = function (v) { return v !== undefined; };
489
529
 
490
530
  var registerInstance = function (vm, callVal) {
491
- var i = vm.$options._parentVnode;
531
+ var i = vm.$options._parentKnode;
492
532
  if (isDef(i) && isDef(i = i.data) && isDef(i = i.registerRouteInstance)) {
493
533
  i(vm, callVal);
494
534
  }
@@ -602,14 +642,14 @@ function cleanPath (path) {
602
642
  return path.replace(/\/\//g, '/')
603
643
  }
604
644
 
605
- var index$1 = Array.isArray || function (arr) {
645
+ var isarray = Array.isArray || function (arr) {
606
646
  return Object.prototype.toString.call(arr) == '[object Array]';
607
647
  };
608
648
 
609
649
  /**
610
650
  * Expose `pathToRegexp`.
611
651
  */
612
- var index = pathToRegexp;
652
+ var pathToRegexp_1 = pathToRegexp;
613
653
  var parse_1 = parse;
614
654
  var compile_1 = compile;
615
655
  var tokensToFunction_1 = tokensToFunction;
@@ -714,7 +754,7 @@ function parse (str, options) {
714
754
  * @return {!function(Object=, Object=)}
715
755
  */
716
756
  function compile (str, options) {
717
- return tokensToFunction(parse(str, options))
757
+ return tokensToFunction(parse(str, options), options)
718
758
  }
719
759
 
720
760
  /**
@@ -744,14 +784,14 @@ function encodeAsterisk (str) {
744
784
  /**
745
785
  * Expose a method for transforming tokens into the path function.
746
786
  */
747
- function tokensToFunction (tokens) {
787
+ function tokensToFunction (tokens, options) {
748
788
  // Compile all the tokens into regexps.
749
789
  var matches = new Array(tokens.length);
750
790
 
751
791
  // Compile all the patterns before compilation.
752
792
  for (var i = 0; i < tokens.length; i++) {
753
793
  if (typeof tokens[i] === 'object') {
754
- matches[i] = new RegExp('^(?:' + tokens[i].pattern + ')$');
794
+ matches[i] = new RegExp('^(?:' + tokens[i].pattern + ')$', flags(options));
755
795
  }
756
796
  }
757
797
 
@@ -786,7 +826,7 @@ function tokensToFunction (tokens) {
786
826
  }
787
827
  }
788
828
 
789
- if (index$1(value)) {
829
+ if (isarray(value)) {
790
830
  if (!token.repeat) {
791
831
  throw new TypeError('Expected "' + token.name + '" to not repeat, but received `' + JSON.stringify(value) + '`')
792
832
  }
@@ -864,7 +904,7 @@ function attachKeys (re, keys) {
864
904
  * @return {string}
865
905
  */
866
906
  function flags (options) {
867
- return options.sensitive ? '' : 'i'
907
+ return options && options.sensitive ? '' : 'i'
868
908
  }
869
909
 
870
910
  /**
@@ -937,7 +977,7 @@ function stringToRegexp (path, keys, options) {
937
977
  * @return {!RegExp}
938
978
  */
939
979
  function tokensToRegExp (tokens, keys, options) {
940
- if (!index$1(keys)) {
980
+ if (!isarray(keys)) {
941
981
  options = /** @type {!Object} */ (keys || options);
942
982
  keys = [];
943
983
  }
@@ -1013,7 +1053,7 @@ function tokensToRegExp (tokens, keys, options) {
1013
1053
  * @return {!RegExp}
1014
1054
  */
1015
1055
  function pathToRegexp (path, keys, options) {
1016
- if (!index$1(keys)) {
1056
+ if (!isarray(keys)) {
1017
1057
  options = /** @type {!Object} */ (keys || options);
1018
1058
  keys = [];
1019
1059
  }
@@ -1024,20 +1064,21 @@ function pathToRegexp (path, keys, options) {
1024
1064
  return regexpToRegexp(path, /** @type {!Array} */ (keys))
1025
1065
  }
1026
1066
 
1027
- if (index$1(path)) {
1067
+ if (isarray(path)) {
1028
1068
  return arrayToRegexp(/** @type {!Array} */ (path), /** @type {!Array} */ (keys), options)
1029
1069
  }
1030
1070
 
1031
1071
  return stringToRegexp(/** @type {string} */ (path), /** @type {!Array} */ (keys), options)
1032
1072
  }
1033
1073
 
1034
- index.parse = parse_1;
1035
- index.compile = compile_1;
1036
- index.tokensToFunction = tokensToFunction_1;
1037
- index.tokensToRegExp = tokensToRegExp_1;
1074
+ pathToRegexp_1.parse = parse_1;
1075
+ pathToRegexp_1.compile = compile_1;
1076
+ pathToRegexp_1.tokensToFunction = tokensToFunction_1;
1077
+ pathToRegexp_1.tokensToRegExp = tokensToRegExp_1;
1038
1078
 
1039
1079
  /* */
1040
1080
 
1081
+ // $flow-disable-line
1041
1082
  var regexpCompileCache = Object.create(null);
1042
1083
 
1043
1084
  function fillParams (
@@ -1048,7 +1089,7 @@ function fillParams (
1048
1089
  try {
1049
1090
  var filler =
1050
1091
  regexpCompileCache[path] ||
1051
- (regexpCompileCache[path] = index.compile(path));
1092
+ (regexpCompileCache[path] = pathToRegexp_1.compile(path));
1052
1093
  return filler(params || {}, { pretty: true })
1053
1094
  } catch (e) {
1054
1095
  if (process.env.NODE_ENV !== 'production') {
@@ -1068,7 +1109,9 @@ function createRouteMap (
1068
1109
  ) {
1069
1110
  // the path list is used to control path matching priority
1070
1111
  var pathList = oldPathList || [];
1112
+ // $flow-disable-line
1071
1113
  var pathMap = oldPathMap || Object.create(null);
1114
+ // $flow-disable-line
1072
1115
  var nameMap = oldNameMap || Object.create(null);
1073
1116
 
1074
1117
  routes.forEach(function (route) {
@@ -1110,8 +1153,12 @@ function addRouteRecord (
1110
1153
  );
1111
1154
  }
1112
1155
 
1113
- var normalizedPath = normalizePath(path, parent);
1114
1156
  var pathToRegexpOptions = route.pathToRegexpOptions || {};
1157
+ var normalizedPath = normalizePath(
1158
+ path,
1159
+ parent,
1160
+ pathToRegexpOptions.strict
1161
+ );
1115
1162
 
1116
1163
  if (typeof route.caseSensitive === 'boolean') {
1117
1164
  pathToRegexpOptions.sensitive = route.caseSensitive;
@@ -1199,9 +1246,9 @@ function addRouteRecord (
1199
1246
  }
1200
1247
 
1201
1248
  function compileRouteRegex (path, pathToRegexpOptions) {
1202
- var regex = index(path, [], pathToRegexpOptions);
1249
+ var regex = pathToRegexp_1(path, [], pathToRegexpOptions);
1203
1250
  if (process.env.NODE_ENV !== 'production') {
1204
- var keys = {};
1251
+ var keys = Object.create(null);
1205
1252
  regex.keys.forEach(function (key) {
1206
1253
  warn(!keys[key.name], ("Duplicate param keys in route with path: \"" + path + "\""));
1207
1254
  keys[key.name] = true;
@@ -1210,8 +1257,8 @@ function compileRouteRegex (path, pathToRegexpOptions) {
1210
1257
  return regex
1211
1258
  }
1212
1259
 
1213
- function normalizePath (path, parent) {
1214
- path = path.replace(/\/$/, '');
1260
+ function normalizePath (path, parent, strict) {
1261
+ if (!strict) { path = path.replace(/\/$/, ''); }
1215
1262
  if (path[0] === '/') { return path }
1216
1263
  if (parent == null) { return path }
1217
1264
  return cleanPath(((parent.path) + "/" + path))
@@ -1483,6 +1530,8 @@ function resolveRecordPath (path, record) {
1483
1530
  var positionStore = Object.create(null);
1484
1531
 
1485
1532
  function setupScroll () {
1533
+ // Fix for #1585 for Firefox
1534
+ window.history.replaceState({ key: getStateKey() }, '');
1486
1535
  window.addEventListener('popstate', function (e) {
1487
1536
  saveScrollPosition();
1488
1537
  if (e.state && e.state.key) {
@@ -1514,25 +1563,21 @@ function handleScroll (
1514
1563
  router.app.$nextTick(function () {
1515
1564
  var position = getScrollPosition();
1516
1565
  var shouldScroll = behavior(to, from, isPop ? position : null);
1566
+
1517
1567
  if (!shouldScroll) {
1518
1568
  return
1519
1569
  }
1520
- var isObject = typeof shouldScroll === 'object';
1521
- if (isObject && typeof shouldScroll.selector === 'string') {
1522
- var el = document.querySelector(shouldScroll.selector);
1523
- if (el) {
1524
- var offset = shouldScroll.offset && typeof shouldScroll.offset === 'object' ? shouldScroll.offset : {};
1525
- offset = normalizeOffset(offset);
1526
- position = getElementPosition(el, offset);
1527
- } else if (isValidPosition(shouldScroll)) {
1528
- position = normalizePosition(shouldScroll);
1529
- }
1530
- } else if (isObject && isValidPosition(shouldScroll)) {
1531
- position = normalizePosition(shouldScroll);
1532
- }
1533
1570
 
1534
- if (position) {
1535
- window.scrollTo(position.x, position.y);
1571
+ if (typeof shouldScroll.then === 'function') {
1572
+ shouldScroll.then(function (shouldScroll) {
1573
+ scrollToPosition((shouldScroll), position);
1574
+ }).catch(function (err) {
1575
+ if (process.env.NODE_ENV !== 'production') {
1576
+ assert(false, err.toString());
1577
+ }
1578
+ });
1579
+ } else {
1580
+ scrollToPosition(shouldScroll, position);
1536
1581
  }
1537
1582
  });
1538
1583
  }
@@ -1586,6 +1631,26 @@ function isNumber (v) {
1586
1631
  return typeof v === 'number'
1587
1632
  }
1588
1633
 
1634
+ function scrollToPosition (shouldScroll, position) {
1635
+ var isObject = typeof shouldScroll === 'object';
1636
+ if (isObject && typeof shouldScroll.selector === 'string') {
1637
+ var el = document.querySelector(shouldScroll.selector);
1638
+ if (el) {
1639
+ var offset = shouldScroll.offset && typeof shouldScroll.offset === 'object' ? shouldScroll.offset : {};
1640
+ offset = normalizeOffset(offset);
1641
+ position = getElementPosition(el, offset);
1642
+ } else if (isValidPosition(shouldScroll)) {
1643
+ position = normalizePosition(shouldScroll);
1644
+ }
1645
+ } else if (isObject && isValidPosition(shouldScroll)) {
1646
+ position = normalizePosition(shouldScroll);
1647
+ }
1648
+
1649
+ if (position) {
1650
+ window.scrollTo(position.x, position.y);
1651
+ }
1652
+ }
1653
+
1589
1654
  /* */
1590
1655
 
1591
1656
  var supportsPushState = inBrowser && (function () {
@@ -1681,7 +1746,7 @@ function resolveAsyncComponents (matched) {
1681
1746
  pending++;
1682
1747
 
1683
1748
  var resolve = once(function (resolvedDef) {
1684
- if (resolvedDef.__esModule && resolvedDef.default) {
1749
+ if (isESModule(resolvedDef)) {
1685
1750
  resolvedDef = resolvedDef.default;
1686
1751
  }
1687
1752
  // save resolved on async factory in case it's used elsewhere
@@ -1716,7 +1781,7 @@ function resolveAsyncComponents (matched) {
1716
1781
  if (typeof res.then === 'function') {
1717
1782
  res.then(resolve, reject);
1718
1783
  } else {
1719
- // new syntax in Kdu
1784
+ // new syntax in Kdu 2.3
1720
1785
  var comp = res.component;
1721
1786
  if (comp && typeof comp.then === 'function') {
1722
1787
  comp.then(resolve, reject);
@@ -1747,6 +1812,14 @@ function flatten (arr) {
1747
1812
  return Array.prototype.concat.apply([], arr)
1748
1813
  }
1749
1814
 
1815
+ var hasSymbol =
1816
+ typeof Symbol === 'function' &&
1817
+ typeof Symbol.toStringTag === 'symbol';
1818
+
1819
+ function isESModule (obj) {
1820
+ return obj.__esModule || (hasSymbol && obj[Symbol.toStringTag] === 'Module')
1821
+ }
1822
+
1750
1823
  // in Webpack 2, require.ensure now also returns a Promise
1751
1824
  // so the resolve/reject functions may get called an extra time
1752
1825
  // if the user uses an arrow function shorthand that happens to
@@ -2075,9 +2148,18 @@ var HTML5History = (function (History$$1) {
2075
2148
  setupScroll();
2076
2149
  }
2077
2150
 
2151
+ var initLocation = getLocation(this.base);
2078
2152
  window.addEventListener('popstate', function (e) {
2079
2153
  var current = this$1.current;
2080
- this$1.transitionTo(getLocation(this$1.base), function (route) {
2154
+
2155
+ // Avoiding first `popstate` event dispatched in some browsers but first
2156
+ // history route not updated since async guard at the same time.
2157
+ var location = getLocation(this$1.base);
2158
+ if (this$1.current === START && location === initLocation) {
2159
+ return
2160
+ }
2161
+
2162
+ this$1.transitionTo(location, function (route) {
2081
2163
  if (expectScroll) {
2082
2164
  handleScroll(router, route, current, true);
2083
2165
  }
@@ -2161,26 +2243,50 @@ var HashHistory = (function (History$$1) {
2161
2243
  HashHistory.prototype.setupListeners = function setupListeners () {
2162
2244
  var this$1 = this;
2163
2245
 
2164
- window.addEventListener('hashchange', function () {
2246
+ var router = this.router;
2247
+ var expectScroll = router.options.scrollBehavior;
2248
+ var supportsScroll = supportsPushState && expectScroll;
2249
+
2250
+ if (supportsScroll) {
2251
+ setupScroll();
2252
+ }
2253
+
2254
+ window.addEventListener(supportsPushState ? 'popstate' : 'hashchange', function () {
2255
+ var current = this$1.current;
2165
2256
  if (!ensureSlash()) {
2166
2257
  return
2167
2258
  }
2168
2259
  this$1.transitionTo(getHash(), function (route) {
2169
- replaceHash(route.fullPath);
2260
+ if (supportsScroll) {
2261
+ handleScroll(this$1.router, route, current, true);
2262
+ }
2263
+ if (!supportsPushState) {
2264
+ replaceHash(route.fullPath);
2265
+ }
2170
2266
  });
2171
2267
  });
2172
2268
  };
2173
2269
 
2174
2270
  HashHistory.prototype.push = function push (location, onComplete, onAbort) {
2271
+ var this$1 = this;
2272
+
2273
+ var ref = this;
2274
+ var fromRoute = ref.current;
2175
2275
  this.transitionTo(location, function (route) {
2176
2276
  pushHash(route.fullPath);
2277
+ handleScroll(this$1.router, route, fromRoute, false);
2177
2278
  onComplete && onComplete(route);
2178
2279
  }, onAbort);
2179
2280
  };
2180
2281
 
2181
2282
  HashHistory.prototype.replace = function replace (location, onComplete, onAbort) {
2283
+ var this$1 = this;
2284
+
2285
+ var ref = this;
2286
+ var fromRoute = ref.current;
2182
2287
  this.transitionTo(location, function (route) {
2183
2288
  replaceHash(route.fullPath);
2289
+ handleScroll(this$1.router, route, fromRoute, false);
2184
2290
  onComplete && onComplete(route);
2185
2291
  }, onAbort);
2186
2292
  };
@@ -2230,15 +2336,27 @@ function getHash () {
2230
2336
  return index === -1 ? '' : href.slice(index + 1)
2231
2337
  }
2232
2338
 
2339
+ function getUrl (path) {
2340
+ var href = window.location.href;
2341
+ var i = href.indexOf('#');
2342
+ var base = i >= 0 ? href.slice(0, i) : href;
2343
+ return (base + "#" + path)
2344
+ }
2345
+
2233
2346
  function pushHash (path) {
2234
- window.location.hash = path;
2347
+ if (supportsPushState) {
2348
+ pushState(getUrl(path));
2349
+ } else {
2350
+ window.location.hash = path;
2351
+ }
2235
2352
  }
2236
2353
 
2237
2354
  function replaceHash (path) {
2238
- var href = window.location.href;
2239
- var i = href.indexOf('#');
2240
- var base = i >= 0 ? href.slice(0, i) : href;
2241
- window.location.replace((base + "#" + path));
2355
+ if (supportsPushState) {
2356
+ replaceState(getUrl(path));
2357
+ } else {
2358
+ window.location.replace(getUrl(path));
2359
+ }
2242
2360
  }
2243
2361
 
2244
2362
  /* */
@@ -2340,7 +2458,7 @@ var KduRouter = function KduRouter (options) {
2340
2458
  }
2341
2459
  };
2342
2460
 
2343
- var prototypeAccessors = { currentRoute: {} };
2461
+ var prototypeAccessors = { currentRoute: { configurable: true } };
2344
2462
 
2345
2463
  KduRouter.prototype.match = function match (
2346
2464
  raw,
@@ -2498,7 +2616,7 @@ function createHref (base, fullPath, mode) {
2498
2616
  }
2499
2617
 
2500
2618
  KduRouter.install = install;
2501
- KduRouter.version = '2.7.0';
2619
+ KduRouter.version = '3.0.1';
2502
2620
 
2503
2621
  if (inBrowser && window.Kdu) {
2504
2622
  window.Kdu.use(KduRouter);