kdu-router 3.5.4 → 4.0.16

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.
Files changed (45) hide show
  1. package/LICENSE +2 -2
  2. package/README.md +10 -4
  3. package/dist/kdu-router.cjs.js +3484 -0
  4. package/dist/kdu-router.cjs.prod.js +2759 -0
  5. package/dist/kdu-router.d.ts +1349 -0
  6. package/dist/kdu-router.esm-browser.js +3460 -0
  7. package/dist/kdu-router.esm-bundler.js +3478 -0
  8. package/dist/kdu-router.global.js +3625 -0
  9. package/dist/kdu-router.global.prod.js +6 -0
  10. package/ketur/attributes.json +8 -14
  11. package/ketur/tags.json +2 -12
  12. package/package.json +77 -71
  13. package/dist/kdu-router.common.js +0 -3147
  14. package/dist/kdu-router.esm.browser.js +0 -3113
  15. package/dist/kdu-router.esm.browser.min.js +0 -11
  16. package/dist/kdu-router.esm.js +0 -3145
  17. package/dist/kdu-router.js +0 -3152
  18. package/dist/kdu-router.min.js +0 -11
  19. package/src/components/link.js +0 -224
  20. package/src/components/view.js +0 -155
  21. package/src/create-matcher.js +0 -226
  22. package/src/create-route-map.js +0 -220
  23. package/src/history/abstract.js +0 -72
  24. package/src/history/base.js +0 -379
  25. package/src/history/hash.js +0 -152
  26. package/src/history/html5.js +0 -99
  27. package/src/index.js +0 -293
  28. package/src/install.js +0 -52
  29. package/src/util/async.js +0 -18
  30. package/src/util/dom.js +0 -3
  31. package/src/util/errors.js +0 -86
  32. package/src/util/location.js +0 -69
  33. package/src/util/misc.js +0 -6
  34. package/src/util/params.js +0 -37
  35. package/src/util/path.js +0 -74
  36. package/src/util/push-state.js +0 -46
  37. package/src/util/query.js +0 -113
  38. package/src/util/resolve-components.js +0 -109
  39. package/src/util/route.js +0 -151
  40. package/src/util/scroll.js +0 -175
  41. package/src/util/state-key.js +0 -22
  42. package/src/util/warn.js +0 -14
  43. package/types/index.d.ts +0 -21
  44. package/types/kdu.d.ts +0 -22
  45. package/types/router.d.ts +0 -211
@@ -1,3147 +0,0 @@
1
- /*!
2
- * kdu-router v3.5.4
3
- * (c) 2022 NKDuy
4
- * @license MIT
5
- */
6
- 'use strict';
7
-
8
- /* */
9
-
10
- function assert (condition, message) {
11
- if (!condition) {
12
- throw new Error(("[kdu-router] " + message))
13
- }
14
- }
15
-
16
- function warn (condition, message) {
17
- if (!condition) {
18
- typeof console !== 'undefined' && console.warn(("[kdu-router] " + message));
19
- }
20
- }
21
-
22
- function extend (a, b) {
23
- for (var key in b) {
24
- a[key] = b[key];
25
- }
26
- return a
27
- }
28
-
29
- /* */
30
-
31
- var encodeReserveRE = /[!'()*]/g;
32
- var encodeReserveReplacer = function (c) { return '%' + c.charCodeAt(0).toString(16); };
33
- var commaRE = /%2C/g;
34
-
35
- // fixed encodeURIComponent which is more conformant to RFC3986:
36
- // - escapes [!'()*]
37
- // - preserve commas
38
- var encode = function (str) { return encodeURIComponent(str)
39
- .replace(encodeReserveRE, encodeReserveReplacer)
40
- .replace(commaRE, ','); };
41
-
42
- function decode (str) {
43
- try {
44
- return decodeURIComponent(str)
45
- } catch (err) {
46
- if (process.env.NODE_ENV !== 'production') {
47
- warn(false, ("Error decoding \"" + str + "\". Leaving it intact."));
48
- }
49
- }
50
- return str
51
- }
52
-
53
- function resolveQuery (
54
- query,
55
- extraQuery,
56
- _parseQuery
57
- ) {
58
- if ( extraQuery === void 0 ) extraQuery = {};
59
-
60
- var parse = _parseQuery || parseQuery;
61
- var parsedQuery;
62
- try {
63
- parsedQuery = parse(query || '');
64
- } catch (e) {
65
- process.env.NODE_ENV !== 'production' && warn(false, e.message);
66
- parsedQuery = {};
67
- }
68
- for (var key in extraQuery) {
69
- var value = extraQuery[key];
70
- parsedQuery[key] = Array.isArray(value)
71
- ? value.map(castQueryParamValue)
72
- : castQueryParamValue(value);
73
- }
74
- return parsedQuery
75
- }
76
-
77
- var castQueryParamValue = function (value) { return (value == null || typeof value === 'object' ? value : String(value)); };
78
-
79
- function parseQuery (query) {
80
- var res = {};
81
-
82
- query = query.trim().replace(/^(\?|#|&)/, '');
83
-
84
- if (!query) {
85
- return res
86
- }
87
-
88
- query.split('&').forEach(function (param) {
89
- var parts = param.replace(/\+/g, ' ').split('=');
90
- var key = decode(parts.shift());
91
- var val = parts.length > 0 ? decode(parts.join('=')) : null;
92
-
93
- if (res[key] === undefined) {
94
- res[key] = val;
95
- } else if (Array.isArray(res[key])) {
96
- res[key].push(val);
97
- } else {
98
- res[key] = [res[key], val];
99
- }
100
- });
101
-
102
- return res
103
- }
104
-
105
- function stringifyQuery (obj) {
106
- var res = obj
107
- ? Object.keys(obj)
108
- .map(function (key) {
109
- var val = obj[key];
110
-
111
- if (val === undefined) {
112
- return ''
113
- }
114
-
115
- if (val === null) {
116
- return encode(key)
117
- }
118
-
119
- if (Array.isArray(val)) {
120
- var result = [];
121
- val.forEach(function (val2) {
122
- if (val2 === undefined) {
123
- return
124
- }
125
- if (val2 === null) {
126
- result.push(encode(key));
127
- } else {
128
- result.push(encode(key) + '=' + encode(val2));
129
- }
130
- });
131
- return result.join('&')
132
- }
133
-
134
- return encode(key) + '=' + encode(val)
135
- })
136
- .filter(function (x) { return x.length > 0; })
137
- .join('&')
138
- : null;
139
- return res ? ("?" + res) : ''
140
- }
141
-
142
- /* */
143
-
144
- var trailingSlashRE = /\/?$/;
145
-
146
- function createRoute (
147
- record,
148
- location,
149
- redirectedFrom,
150
- router
151
- ) {
152
- var stringifyQuery = router && router.options.stringifyQuery;
153
-
154
- var query = location.query || {};
155
- try {
156
- query = clone(query);
157
- } catch (e) {}
158
-
159
- var route = {
160
- name: location.name || (record && record.name),
161
- meta: (record && record.meta) || {},
162
- path: location.path || '/',
163
- hash: location.hash || '',
164
- query: query,
165
- params: location.params || {},
166
- fullPath: getFullPath(location, stringifyQuery),
167
- matched: record ? formatMatch(record) : []
168
- };
169
- if (redirectedFrom) {
170
- route.redirectedFrom = getFullPath(redirectedFrom, stringifyQuery);
171
- }
172
- return Object.freeze(route)
173
- }
174
-
175
- function clone (value) {
176
- if (Array.isArray(value)) {
177
- return value.map(clone)
178
- } else if (value && typeof value === 'object') {
179
- var res = {};
180
- for (var key in value) {
181
- res[key] = clone(value[key]);
182
- }
183
- return res
184
- } else {
185
- return value
186
- }
187
- }
188
-
189
- // the starting route that represents the initial state
190
- var START = createRoute(null, {
191
- path: '/'
192
- });
193
-
194
- function formatMatch (record) {
195
- var res = [];
196
- while (record) {
197
- res.unshift(record);
198
- record = record.parent;
199
- }
200
- return res
201
- }
202
-
203
- function getFullPath (
204
- ref,
205
- _stringifyQuery
206
- ) {
207
- var path = ref.path;
208
- var query = ref.query; if ( query === void 0 ) query = {};
209
- var hash = ref.hash; if ( hash === void 0 ) hash = '';
210
-
211
- var stringify = _stringifyQuery || stringifyQuery;
212
- return (path || '/') + stringify(query) + hash
213
- }
214
-
215
- function isSameRoute (a, b, onlyPath) {
216
- if (b === START) {
217
- return a === b
218
- } else if (!b) {
219
- return false
220
- } else if (a.path && b.path) {
221
- return a.path.replace(trailingSlashRE, '') === b.path.replace(trailingSlashRE, '') && (onlyPath ||
222
- a.hash === b.hash &&
223
- isObjectEqual(a.query, b.query))
224
- } else if (a.name && b.name) {
225
- return (
226
- a.name === b.name &&
227
- (onlyPath || (
228
- a.hash === b.hash &&
229
- isObjectEqual(a.query, b.query) &&
230
- isObjectEqual(a.params, b.params))
231
- )
232
- )
233
- } else {
234
- return false
235
- }
236
- }
237
-
238
- function isObjectEqual (a, b) {
239
- if ( a === void 0 ) a = {};
240
- if ( b === void 0 ) b = {};
241
-
242
- // handle null value #1566
243
- if (!a || !b) { return a === b }
244
- var aKeys = Object.keys(a).sort();
245
- var bKeys = Object.keys(b).sort();
246
- if (aKeys.length !== bKeys.length) {
247
- return false
248
- }
249
- return aKeys.every(function (key, i) {
250
- var aVal = a[key];
251
- var bKey = bKeys[i];
252
- if (bKey !== key) { return false }
253
- var bVal = b[key];
254
- // query values can be null and undefined
255
- if (aVal == null || bVal == null) { return aVal === bVal }
256
- // check nested equality
257
- if (typeof aVal === 'object' && typeof bVal === 'object') {
258
- return isObjectEqual(aVal, bVal)
259
- }
260
- return String(aVal) === String(bVal)
261
- })
262
- }
263
-
264
- function isIncludedRoute (current, target) {
265
- return (
266
- current.path.replace(trailingSlashRE, '/').indexOf(
267
- target.path.replace(trailingSlashRE, '/')
268
- ) === 0 &&
269
- (!target.hash || current.hash === target.hash) &&
270
- queryIncludes(current.query, target.query)
271
- )
272
- }
273
-
274
- function queryIncludes (current, target) {
275
- for (var key in target) {
276
- if (!(key in current)) {
277
- return false
278
- }
279
- }
280
- return true
281
- }
282
-
283
- function handleRouteEntered (route) {
284
- for (var i = 0; i < route.matched.length; i++) {
285
- var record = route.matched[i];
286
- for (var name in record.instances) {
287
- var instance = record.instances[name];
288
- var cbs = record.enteredCbs[name];
289
- if (!instance || !cbs) { continue }
290
- delete record.enteredCbs[name];
291
- for (var i$1 = 0; i$1 < cbs.length; i$1++) {
292
- if (!instance._isBeingDestroyed) { cbs[i$1](instance); }
293
- }
294
- }
295
- }
296
- }
297
-
298
- var View = {
299
- name: 'RouterView',
300
- functional: true,
301
- props: {
302
- name: {
303
- type: String,
304
- default: 'default'
305
- }
306
- },
307
- render: function render (_, ref) {
308
- var props = ref.props;
309
- var children = ref.children;
310
- var parent = ref.parent;
311
- var data = ref.data;
312
-
313
- // used by devtools to display a router-view badge
314
- data.routerView = true;
315
-
316
- // directly use parent context's createElement() function
317
- // so that components rendered by router-view can resolve named slots
318
- var h = parent.$createElement;
319
- var name = props.name;
320
- var route = parent.$route;
321
- var cache = parent._routerViewCache || (parent._routerViewCache = {});
322
-
323
- // determine current view depth, also check to see if the tree
324
- // has been toggled inactive but kept-alive.
325
- var depth = 0;
326
- var inactive = false;
327
- while (parent && parent._routerRoot !== parent) {
328
- var knodeData = parent.$knode ? parent.$knode.data : {};
329
- if (knodeData.routerView) {
330
- depth++;
331
- }
332
- if (knodeData.keepAlive && parent._directInactive && parent._inactive) {
333
- inactive = true;
334
- }
335
- parent = parent.$parent;
336
- }
337
- data.routerViewDepth = depth;
338
-
339
- // render previous view if the tree is inactive and kept-alive
340
- if (inactive) {
341
- var cachedData = cache[name];
342
- var cachedComponent = cachedData && cachedData.component;
343
- if (cachedComponent) {
344
- // #2301
345
- // pass props
346
- if (cachedData.configProps) {
347
- fillPropsinData(cachedComponent, data, cachedData.route, cachedData.configProps);
348
- }
349
- return h(cachedComponent, data, children)
350
- } else {
351
- // render previous empty view
352
- return h()
353
- }
354
- }
355
-
356
- var matched = route.matched[depth];
357
- var component = matched && matched.components[name];
358
-
359
- // render empty node if no matched route or no config component
360
- if (!matched || !component) {
361
- cache[name] = null;
362
- return h()
363
- }
364
-
365
- // cache component
366
- cache[name] = { component: component };
367
-
368
- // attach instance registration hook
369
- // this will be called in the instance's injected lifecycle hooks
370
- data.registerRouteInstance = function (vm, val) {
371
- // val could be undefined for unregistration
372
- var current = matched.instances[name];
373
- if (
374
- (val && current !== vm) ||
375
- (!val && current === vm)
376
- ) {
377
- matched.instances[name] = val;
378
- }
379
- }
380
-
381
- // also register instance in prepatch hook
382
- // in case the same component instance is reused across different routes
383
- ;(data.hook || (data.hook = {})).prepatch = function (_, knode) {
384
- matched.instances[name] = knode.componentInstance;
385
- };
386
-
387
- // register instance in init hook
388
- // in case kept-alive component be actived when routes changed
389
- data.hook.init = function (knode) {
390
- if (knode.data.keepAlive &&
391
- knode.componentInstance &&
392
- knode.componentInstance !== matched.instances[name]
393
- ) {
394
- matched.instances[name] = knode.componentInstance;
395
- }
396
-
397
- // if the route transition has already been confirmed then we weren't
398
- // able to call the cbs during confirmation as the component was not
399
- // registered yet, so we call it here.
400
- handleRouteEntered(route);
401
- };
402
-
403
- var configProps = matched.props && matched.props[name];
404
- // save route and configProps in cache
405
- if (configProps) {
406
- extend(cache[name], {
407
- route: route,
408
- configProps: configProps
409
- });
410
- fillPropsinData(component, data, route, configProps);
411
- }
412
-
413
- return h(component, data, children)
414
- }
415
- };
416
-
417
- function fillPropsinData (component, data, route, configProps) {
418
- // resolve props
419
- var propsToPass = data.props = resolveProps(route, configProps);
420
- if (propsToPass) {
421
- // clone to prevent mutation
422
- propsToPass = data.props = extend({}, propsToPass);
423
- // pass non-declared props as attrs
424
- var attrs = data.attrs = data.attrs || {};
425
- for (var key in propsToPass) {
426
- if (!component.props || !(key in component.props)) {
427
- attrs[key] = propsToPass[key];
428
- delete propsToPass[key];
429
- }
430
- }
431
- }
432
- }
433
-
434
- function resolveProps (route, config) {
435
- switch (typeof config) {
436
- case 'undefined':
437
- return
438
- case 'object':
439
- return config
440
- case 'function':
441
- return config(route)
442
- case 'boolean':
443
- return config ? route.params : undefined
444
- default:
445
- if (process.env.NODE_ENV !== 'production') {
446
- warn(
447
- false,
448
- "props in \"" + (route.path) + "\" is a " + (typeof config) + ", " +
449
- "expecting an object, function or boolean."
450
- );
451
- }
452
- }
453
- }
454
-
455
- /* */
456
-
457
- function resolvePath (
458
- relative,
459
- base,
460
- append
461
- ) {
462
- var firstChar = relative.charAt(0);
463
- if (firstChar === '/') {
464
- return relative
465
- }
466
-
467
- if (firstChar === '?' || firstChar === '#') {
468
- return base + relative
469
- }
470
-
471
- var stack = base.split('/');
472
-
473
- // remove trailing segment if:
474
- // - not appending
475
- // - appending to trailing slash (last segment is empty)
476
- if (!append || !stack[stack.length - 1]) {
477
- stack.pop();
478
- }
479
-
480
- // resolve relative path
481
- var segments = relative.replace(/^\//, '').split('/');
482
- for (var i = 0; i < segments.length; i++) {
483
- var segment = segments[i];
484
- if (segment === '..') {
485
- stack.pop();
486
- } else if (segment !== '.') {
487
- stack.push(segment);
488
- }
489
- }
490
-
491
- // ensure leading slash
492
- if (stack[0] !== '') {
493
- stack.unshift('');
494
- }
495
-
496
- return stack.join('/')
497
- }
498
-
499
- function parsePath (path) {
500
- var hash = '';
501
- var query = '';
502
-
503
- var hashIndex = path.indexOf('#');
504
- if (hashIndex >= 0) {
505
- hash = path.slice(hashIndex);
506
- path = path.slice(0, hashIndex);
507
- }
508
-
509
- var queryIndex = path.indexOf('?');
510
- if (queryIndex >= 0) {
511
- query = path.slice(queryIndex + 1);
512
- path = path.slice(0, queryIndex);
513
- }
514
-
515
- return {
516
- path: path,
517
- query: query,
518
- hash: hash
519
- }
520
- }
521
-
522
- function cleanPath (path) {
523
- return path.replace(/\/(?:\s*\/)+/g, '/')
524
- }
525
-
526
- var isarray = Array.isArray || function (arr) {
527
- return Object.prototype.toString.call(arr) == '[object Array]';
528
- };
529
-
530
- /**
531
- * Expose `pathToRegexp`.
532
- */
533
- var pathToRegexp_1 = pathToRegexp;
534
- var parse_1 = parse;
535
- var compile_1 = compile;
536
- var tokensToFunction_1 = tokensToFunction;
537
- var tokensToRegExp_1 = tokensToRegExp;
538
-
539
- /**
540
- * The main path matching regexp utility.
541
- *
542
- * @type {RegExp}
543
- */
544
- var PATH_REGEXP = new RegExp([
545
- // Match escaped characters that would otherwise appear in future matches.
546
- // This allows the user to escape special characters that won't transform.
547
- '(\\\\.)',
548
- // Match Express-style parameters and un-named parameters with a prefix
549
- // and optional suffixes. Matches appear as:
550
- //
551
- // "/:test(\\d+)?" => ["/", "test", "\d+", undefined, "?", undefined]
552
- // "/route(\\d+)" => [undefined, undefined, undefined, "\d+", undefined, undefined]
553
- // "/*" => ["/", undefined, undefined, undefined, undefined, "*"]
554
- '([\\/.])?(?:(?:\\:(\\w+)(?:\\(((?:\\\\.|[^\\\\()])+)\\))?|\\(((?:\\\\.|[^\\\\()])+)\\))([+*?])?|(\\*))'
555
- ].join('|'), 'g');
556
-
557
- /**
558
- * Parse a string for the raw tokens.
559
- *
560
- * @param {string} str
561
- * @param {Object=} options
562
- * @return {!Array}
563
- */
564
- function parse (str, options) {
565
- var tokens = [];
566
- var key = 0;
567
- var index = 0;
568
- var path = '';
569
- var defaultDelimiter = options && options.delimiter || '/';
570
- var res;
571
-
572
- while ((res = PATH_REGEXP.exec(str)) != null) {
573
- var m = res[0];
574
- var escaped = res[1];
575
- var offset = res.index;
576
- path += str.slice(index, offset);
577
- index = offset + m.length;
578
-
579
- // Ignore already escaped sequences.
580
- if (escaped) {
581
- path += escaped[1];
582
- continue
583
- }
584
-
585
- var next = str[index];
586
- var prefix = res[2];
587
- var name = res[3];
588
- var capture = res[4];
589
- var group = res[5];
590
- var modifier = res[6];
591
- var asterisk = res[7];
592
-
593
- // Push the current path onto the tokens.
594
- if (path) {
595
- tokens.push(path);
596
- path = '';
597
- }
598
-
599
- var partial = prefix != null && next != null && next !== prefix;
600
- var repeat = modifier === '+' || modifier === '*';
601
- var optional = modifier === '?' || modifier === '*';
602
- var delimiter = res[2] || defaultDelimiter;
603
- var pattern = capture || group;
604
-
605
- tokens.push({
606
- name: name || key++,
607
- prefix: prefix || '',
608
- delimiter: delimiter,
609
- optional: optional,
610
- repeat: repeat,
611
- partial: partial,
612
- asterisk: !!asterisk,
613
- pattern: pattern ? escapeGroup(pattern) : (asterisk ? '.*' : '[^' + escapeString(delimiter) + ']+?')
614
- });
615
- }
616
-
617
- // Match any characters still remaining.
618
- if (index < str.length) {
619
- path += str.substr(index);
620
- }
621
-
622
- // If the path exists, push it onto the end.
623
- if (path) {
624
- tokens.push(path);
625
- }
626
-
627
- return tokens
628
- }
629
-
630
- /**
631
- * Compile a string to a template function for the path.
632
- *
633
- * @param {string} str
634
- * @param {Object=} options
635
- * @return {!function(Object=, Object=)}
636
- */
637
- function compile (str, options) {
638
- return tokensToFunction(parse(str, options), options)
639
- }
640
-
641
- /**
642
- * Prettier encoding of URI path segments.
643
- *
644
- * @param {string}
645
- * @return {string}
646
- */
647
- function encodeURIComponentPretty (str) {
648
- return encodeURI(str).replace(/[\/?#]/g, function (c) {
649
- return '%' + c.charCodeAt(0).toString(16).toUpperCase()
650
- })
651
- }
652
-
653
- /**
654
- * Encode the asterisk parameter. Similar to `pretty`, but allows slashes.
655
- *
656
- * @param {string}
657
- * @return {string}
658
- */
659
- function encodeAsterisk (str) {
660
- return encodeURI(str).replace(/[?#]/g, function (c) {
661
- return '%' + c.charCodeAt(0).toString(16).toUpperCase()
662
- })
663
- }
664
-
665
- /**
666
- * Expose a method for transforming tokens into the path function.
667
- */
668
- function tokensToFunction (tokens, options) {
669
- // Compile all the tokens into regexps.
670
- var matches = new Array(tokens.length);
671
-
672
- // Compile all the patterns before compilation.
673
- for (var i = 0; i < tokens.length; i++) {
674
- if (typeof tokens[i] === 'object') {
675
- matches[i] = new RegExp('^(?:' + tokens[i].pattern + ')$', flags(options));
676
- }
677
- }
678
-
679
- return function (obj, opts) {
680
- var path = '';
681
- var data = obj || {};
682
- var options = opts || {};
683
- var encode = options.pretty ? encodeURIComponentPretty : encodeURIComponent;
684
-
685
- for (var i = 0; i < tokens.length; i++) {
686
- var token = tokens[i];
687
-
688
- if (typeof token === 'string') {
689
- path += token;
690
-
691
- continue
692
- }
693
-
694
- var value = data[token.name];
695
- var segment;
696
-
697
- if (value == null) {
698
- if (token.optional) {
699
- // Prepend partial segment prefixes.
700
- if (token.partial) {
701
- path += token.prefix;
702
- }
703
-
704
- continue
705
- } else {
706
- throw new TypeError('Expected "' + token.name + '" to be defined')
707
- }
708
- }
709
-
710
- if (isarray(value)) {
711
- if (!token.repeat) {
712
- throw new TypeError('Expected "' + token.name + '" to not repeat, but received `' + JSON.stringify(value) + '`')
713
- }
714
-
715
- if (value.length === 0) {
716
- if (token.optional) {
717
- continue
718
- } else {
719
- throw new TypeError('Expected "' + token.name + '" to not be empty')
720
- }
721
- }
722
-
723
- for (var j = 0; j < value.length; j++) {
724
- segment = encode(value[j]);
725
-
726
- if (!matches[i].test(segment)) {
727
- throw new TypeError('Expected all "' + token.name + '" to match "' + token.pattern + '", but received `' + JSON.stringify(segment) + '`')
728
- }
729
-
730
- path += (j === 0 ? token.prefix : token.delimiter) + segment;
731
- }
732
-
733
- continue
734
- }
735
-
736
- segment = token.asterisk ? encodeAsterisk(value) : encode(value);
737
-
738
- if (!matches[i].test(segment)) {
739
- throw new TypeError('Expected "' + token.name + '" to match "' + token.pattern + '", but received "' + segment + '"')
740
- }
741
-
742
- path += token.prefix + segment;
743
- }
744
-
745
- return path
746
- }
747
- }
748
-
749
- /**
750
- * Escape a regular expression string.
751
- *
752
- * @param {string} str
753
- * @return {string}
754
- */
755
- function escapeString (str) {
756
- return str.replace(/([.+*?=^!:${}()[\]|\/\\])/g, '\\$1')
757
- }
758
-
759
- /**
760
- * Escape the capturing group by escaping special characters and meaning.
761
- *
762
- * @param {string} group
763
- * @return {string}
764
- */
765
- function escapeGroup (group) {
766
- return group.replace(/([=!:$\/()])/g, '\\$1')
767
- }
768
-
769
- /**
770
- * Attach the keys as a property of the regexp.
771
- *
772
- * @param {!RegExp} re
773
- * @param {Array} keys
774
- * @return {!RegExp}
775
- */
776
- function attachKeys (re, keys) {
777
- re.keys = keys;
778
- return re
779
- }
780
-
781
- /**
782
- * Get the flags for a regexp from the options.
783
- *
784
- * @param {Object} options
785
- * @return {string}
786
- */
787
- function flags (options) {
788
- return options && options.sensitive ? '' : 'i'
789
- }
790
-
791
- /**
792
- * Pull out keys from a regexp.
793
- *
794
- * @param {!RegExp} path
795
- * @param {!Array} keys
796
- * @return {!RegExp}
797
- */
798
- function regexpToRegexp (path, keys) {
799
- // Use a negative lookahead to match only capturing groups.
800
- var groups = path.source.match(/\((?!\?)/g);
801
-
802
- if (groups) {
803
- for (var i = 0; i < groups.length; i++) {
804
- keys.push({
805
- name: i,
806
- prefix: null,
807
- delimiter: null,
808
- optional: false,
809
- repeat: false,
810
- partial: false,
811
- asterisk: false,
812
- pattern: null
813
- });
814
- }
815
- }
816
-
817
- return attachKeys(path, keys)
818
- }
819
-
820
- /**
821
- * Transform an array into a regexp.
822
- *
823
- * @param {!Array} path
824
- * @param {Array} keys
825
- * @param {!Object} options
826
- * @return {!RegExp}
827
- */
828
- function arrayToRegexp (path, keys, options) {
829
- var parts = [];
830
-
831
- for (var i = 0; i < path.length; i++) {
832
- parts.push(pathToRegexp(path[i], keys, options).source);
833
- }
834
-
835
- var regexp = new RegExp('(?:' + parts.join('|') + ')', flags(options));
836
-
837
- return attachKeys(regexp, keys)
838
- }
839
-
840
- /**
841
- * Create a path regexp from string input.
842
- *
843
- * @param {string} path
844
- * @param {!Array} keys
845
- * @param {!Object} options
846
- * @return {!RegExp}
847
- */
848
- function stringToRegexp (path, keys, options) {
849
- return tokensToRegExp(parse(path, options), keys, options)
850
- }
851
-
852
- /**
853
- * Expose a function for taking tokens and returning a RegExp.
854
- *
855
- * @param {!Array} tokens
856
- * @param {(Array|Object)=} keys
857
- * @param {Object=} options
858
- * @return {!RegExp}
859
- */
860
- function tokensToRegExp (tokens, keys, options) {
861
- if (!isarray(keys)) {
862
- options = /** @type {!Object} */ (keys || options);
863
- keys = [];
864
- }
865
-
866
- options = options || {};
867
-
868
- var strict = options.strict;
869
- var end = options.end !== false;
870
- var route = '';
871
-
872
- // Iterate over the tokens and create our regexp string.
873
- for (var i = 0; i < tokens.length; i++) {
874
- var token = tokens[i];
875
-
876
- if (typeof token === 'string') {
877
- route += escapeString(token);
878
- } else {
879
- var prefix = escapeString(token.prefix);
880
- var capture = '(?:' + token.pattern + ')';
881
-
882
- keys.push(token);
883
-
884
- if (token.repeat) {
885
- capture += '(?:' + prefix + capture + ')*';
886
- }
887
-
888
- if (token.optional) {
889
- if (!token.partial) {
890
- capture = '(?:' + prefix + '(' + capture + '))?';
891
- } else {
892
- capture = prefix + '(' + capture + ')?';
893
- }
894
- } else {
895
- capture = prefix + '(' + capture + ')';
896
- }
897
-
898
- route += capture;
899
- }
900
- }
901
-
902
- var delimiter = escapeString(options.delimiter || '/');
903
- var endsWithDelimiter = route.slice(-delimiter.length) === delimiter;
904
-
905
- // In non-strict mode we allow a slash at the end of match. If the path to
906
- // match already ends with a slash, we remove it for consistency. The slash
907
- // is valid at the end of a path match, not in the middle. This is important
908
- // in non-ending mode, where "/test/" shouldn't match "/test//route".
909
- if (!strict) {
910
- route = (endsWithDelimiter ? route.slice(0, -delimiter.length) : route) + '(?:' + delimiter + '(?=$))?';
911
- }
912
-
913
- if (end) {
914
- route += '$';
915
- } else {
916
- // In non-ending mode, we need the capturing groups to match as much as
917
- // possible by using a positive lookahead to the end or next path segment.
918
- route += strict && endsWithDelimiter ? '' : '(?=' + delimiter + '|$)';
919
- }
920
-
921
- return attachKeys(new RegExp('^' + route, flags(options)), keys)
922
- }
923
-
924
- /**
925
- * Normalize the given path string, returning a regular expression.
926
- *
927
- * An empty array can be passed in for the keys, which will hold the
928
- * placeholder key descriptions. For example, using `/user/:id`, `keys` will
929
- * contain `[{ name: 'id', delimiter: '/', optional: false, repeat: false }]`.
930
- *
931
- * @param {(string|RegExp|Array)} path
932
- * @param {(Array|Object)=} keys
933
- * @param {Object=} options
934
- * @return {!RegExp}
935
- */
936
- function pathToRegexp (path, keys, options) {
937
- if (!isarray(keys)) {
938
- options = /** @type {!Object} */ (keys || options);
939
- keys = [];
940
- }
941
-
942
- options = options || {};
943
-
944
- if (path instanceof RegExp) {
945
- return regexpToRegexp(path, /** @type {!Array} */ (keys))
946
- }
947
-
948
- if (isarray(path)) {
949
- return arrayToRegexp(/** @type {!Array} */ (path), /** @type {!Array} */ (keys), options)
950
- }
951
-
952
- return stringToRegexp(/** @type {string} */ (path), /** @type {!Array} */ (keys), options)
953
- }
954
- pathToRegexp_1.parse = parse_1;
955
- pathToRegexp_1.compile = compile_1;
956
- pathToRegexp_1.tokensToFunction = tokensToFunction_1;
957
- pathToRegexp_1.tokensToRegExp = tokensToRegExp_1;
958
-
959
- /* */
960
-
961
- // $flow-disable-line
962
- var regexpCompileCache = Object.create(null);
963
-
964
- function fillParams (
965
- path,
966
- params,
967
- routeMsg
968
- ) {
969
- params = params || {};
970
- try {
971
- var filler =
972
- regexpCompileCache[path] ||
973
- (regexpCompileCache[path] = pathToRegexp_1.compile(path));
974
-
975
- // Fix #2505 resolving asterisk routes { name: 'not-found', params: { pathMatch: '/not-found' }}
976
- // and fix #3106 so that you can work with location descriptor object having params.pathMatch equal to empty string
977
- if (typeof params.pathMatch === 'string') { params[0] = params.pathMatch; }
978
-
979
- return filler(params, { pretty: true })
980
- } catch (e) {
981
- if (process.env.NODE_ENV !== 'production') {
982
- // Fix #3072 no warn if `pathMatch` is string
983
- warn(typeof params.pathMatch === 'string', ("missing param for " + routeMsg + ": " + (e.message)));
984
- }
985
- return ''
986
- } finally {
987
- // delete the 0 if it was added
988
- delete params[0];
989
- }
990
- }
991
-
992
- /* */
993
-
994
- function normalizeLocation (
995
- raw,
996
- current,
997
- append,
998
- router
999
- ) {
1000
- var next = typeof raw === 'string' ? { path: raw } : raw;
1001
- // named target
1002
- if (next._normalized) {
1003
- return next
1004
- } else if (next.name) {
1005
- next = extend({}, raw);
1006
- var params = next.params;
1007
- if (params && typeof params === 'object') {
1008
- next.params = extend({}, params);
1009
- }
1010
- return next
1011
- }
1012
-
1013
- // relative params
1014
- if (!next.path && next.params && current) {
1015
- next = extend({}, next);
1016
- next._normalized = true;
1017
- var params$1 = extend(extend({}, current.params), next.params);
1018
- if (current.name) {
1019
- next.name = current.name;
1020
- next.params = params$1;
1021
- } else if (current.matched.length) {
1022
- var rawPath = current.matched[current.matched.length - 1].path;
1023
- next.path = fillParams(rawPath, params$1, ("path " + (current.path)));
1024
- } else if (process.env.NODE_ENV !== 'production') {
1025
- warn(false, "relative params navigation requires a current route.");
1026
- }
1027
- return next
1028
- }
1029
-
1030
- var parsedPath = parsePath(next.path || '');
1031
- var basePath = (current && current.path) || '/';
1032
- var path = parsedPath.path
1033
- ? resolvePath(parsedPath.path, basePath, append || next.append)
1034
- : basePath;
1035
-
1036
- var query = resolveQuery(
1037
- parsedPath.query,
1038
- next.query,
1039
- router && router.options.parseQuery
1040
- );
1041
-
1042
- var hash = next.hash || parsedPath.hash;
1043
- if (hash && hash.charAt(0) !== '#') {
1044
- hash = "#" + hash;
1045
- }
1046
-
1047
- return {
1048
- _normalized: true,
1049
- path: path,
1050
- query: query,
1051
- hash: hash
1052
- }
1053
- }
1054
-
1055
- /* */
1056
-
1057
- // work around weird flow bug
1058
- var toTypes = [String, Object];
1059
- var eventTypes = [String, Array];
1060
-
1061
- var noop = function () {};
1062
-
1063
- var warnedCustomSlot;
1064
- var warnedTagProp;
1065
- var warnedEventProp;
1066
-
1067
- var Link = {
1068
- name: 'RouterLink',
1069
- props: {
1070
- to: {
1071
- type: toTypes,
1072
- required: true
1073
- },
1074
- tag: {
1075
- type: String,
1076
- default: 'a'
1077
- },
1078
- custom: Boolean,
1079
- exact: Boolean,
1080
- exactPath: Boolean,
1081
- append: Boolean,
1082
- replace: Boolean,
1083
- activeClass: String,
1084
- exactActiveClass: String,
1085
- ariaCurrentValue: {
1086
- type: String,
1087
- default: 'page'
1088
- },
1089
- event: {
1090
- type: eventTypes,
1091
- default: 'click'
1092
- }
1093
- },
1094
- render: function render (h) {
1095
- var this$1 = this;
1096
-
1097
- var router = this.$router;
1098
- var current = this.$route;
1099
- var ref = router.resolve(
1100
- this.to,
1101
- current,
1102
- this.append
1103
- );
1104
- var location = ref.location;
1105
- var route = ref.route;
1106
- var href = ref.href;
1107
-
1108
- var classes = {};
1109
- var globalActiveClass = router.options.linkActiveClass;
1110
- var globalExactActiveClass = router.options.linkExactActiveClass;
1111
- // Support global empty active class
1112
- var activeClassFallback =
1113
- globalActiveClass == null ? 'router-link-active' : globalActiveClass;
1114
- var exactActiveClassFallback =
1115
- globalExactActiveClass == null
1116
- ? 'router-link-exact-active'
1117
- : globalExactActiveClass;
1118
- var activeClass =
1119
- this.activeClass == null ? activeClassFallback : this.activeClass;
1120
- var exactActiveClass =
1121
- this.exactActiveClass == null
1122
- ? exactActiveClassFallback
1123
- : this.exactActiveClass;
1124
-
1125
- var compareTarget = route.redirectedFrom
1126
- ? createRoute(null, normalizeLocation(route.redirectedFrom), null, router)
1127
- : route;
1128
-
1129
- classes[exactActiveClass] = isSameRoute(current, compareTarget, this.exactPath);
1130
- classes[activeClass] = this.exact || this.exactPath
1131
- ? classes[exactActiveClass]
1132
- : isIncludedRoute(current, compareTarget);
1133
-
1134
- var ariaCurrentValue = classes[exactActiveClass] ? this.ariaCurrentValue : null;
1135
-
1136
- var handler = function (e) {
1137
- if (guardEvent(e)) {
1138
- if (this$1.replace) {
1139
- router.replace(location, noop);
1140
- } else {
1141
- router.push(location, noop);
1142
- }
1143
- }
1144
- };
1145
-
1146
- var on = { click: guardEvent };
1147
- if (Array.isArray(this.event)) {
1148
- this.event.forEach(function (e) {
1149
- on[e] = handler;
1150
- });
1151
- } else {
1152
- on[this.event] = handler;
1153
- }
1154
-
1155
- var data = { class: classes };
1156
-
1157
- var scopedSlot =
1158
- !this.$scopedSlots.$hasNormal &&
1159
- this.$scopedSlots.default &&
1160
- this.$scopedSlots.default({
1161
- href: href,
1162
- route: route,
1163
- navigate: handler,
1164
- isActive: classes[activeClass],
1165
- isExactActive: classes[exactActiveClass]
1166
- });
1167
-
1168
- if (scopedSlot) {
1169
- if (process.env.NODE_ENV !== 'production' && !this.custom) {
1170
- !warnedCustomSlot && warn(false, 'In Kdu Router 4, the k-slot API will by default wrap its content with an <a> element. Use the custom prop to remove this warning:\n<router-link k-slot="{ navigate, href }" custom></router-link>\n');
1171
- warnedCustomSlot = true;
1172
- }
1173
- if (scopedSlot.length === 1) {
1174
- return scopedSlot[0]
1175
- } else if (scopedSlot.length > 1 || !scopedSlot.length) {
1176
- if (process.env.NODE_ENV !== 'production') {
1177
- warn(
1178
- false,
1179
- ("<router-link> 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.")
1180
- );
1181
- }
1182
- return scopedSlot.length === 0 ? h() : h('span', {}, scopedSlot)
1183
- }
1184
- }
1185
-
1186
- if (process.env.NODE_ENV !== 'production') {
1187
- if ('tag' in this.$options.propsData && !warnedTagProp) {
1188
- warn(
1189
- false,
1190
- "<router-link>'s tag prop is deprecated and has been removed in Kdu Router 4. Use the k-slot API to remove this warning: https://kdujs-router.web.app/guide/migration/#removal-of-event-and-tag-props-in-router-link."
1191
- );
1192
- warnedTagProp = true;
1193
- }
1194
- if ('event' in this.$options.propsData && !warnedEventProp) {
1195
- warn(
1196
- false,
1197
- "<router-link>'s event prop is deprecated and has been removed in Kdu Router 4. Use the k-slot API to remove this warning: https://kdujs-router.web.app/guide/migration/#removal-of-event-and-tag-props-in-router-link."
1198
- );
1199
- warnedEventProp = true;
1200
- }
1201
- }
1202
-
1203
- if (this.tag === 'a') {
1204
- data.on = on;
1205
- data.attrs = { href: href, 'aria-current': ariaCurrentValue };
1206
- } else {
1207
- // find the first <a> child and apply listener and href
1208
- var a = findAnchor(this.$slots.default);
1209
- if (a) {
1210
- // in case the <a> is a static node
1211
- a.isStatic = false;
1212
- var aData = (a.data = extend({}, a.data));
1213
- aData.on = aData.on || {};
1214
- // transform existing events in both objects into arrays so we can push later
1215
- for (var event in aData.on) {
1216
- var handler$1 = aData.on[event];
1217
- if (event in on) {
1218
- aData.on[event] = Array.isArray(handler$1) ? handler$1 : [handler$1];
1219
- }
1220
- }
1221
- // append new listeners for router-link
1222
- for (var event$1 in on) {
1223
- if (event$1 in aData.on) {
1224
- // on[event] is always a function
1225
- aData.on[event$1].push(on[event$1]);
1226
- } else {
1227
- aData.on[event$1] = handler;
1228
- }
1229
- }
1230
-
1231
- var aAttrs = (a.data.attrs = extend({}, a.data.attrs));
1232
- aAttrs.href = href;
1233
- aAttrs['aria-current'] = ariaCurrentValue;
1234
- } else {
1235
- // doesn't have <a> child, apply listener to self
1236
- data.on = on;
1237
- }
1238
- }
1239
-
1240
- return h(this.tag, data, this.$slots.default)
1241
- }
1242
- };
1243
-
1244
- function guardEvent (e) {
1245
- // don't redirect with control keys
1246
- if (e.metaKey || e.altKey || e.ctrlKey || e.shiftKey) { return }
1247
- // don't redirect when preventDefault called
1248
- if (e.defaultPrevented) { return }
1249
- // don't redirect on right click
1250
- if (e.button !== undefined && e.button !== 0) { return }
1251
- // don't redirect if `target="_blank"`
1252
- if (e.currentTarget && e.currentTarget.getAttribute) {
1253
- var target = e.currentTarget.getAttribute('target');
1254
- if (/\b_blank\b/i.test(target)) { return }
1255
- }
1256
- // this may be a Weex event which doesn't have this method
1257
- if (e.preventDefault) {
1258
- e.preventDefault();
1259
- }
1260
- return true
1261
- }
1262
-
1263
- function findAnchor (children) {
1264
- if (children) {
1265
- var child;
1266
- for (var i = 0; i < children.length; i++) {
1267
- child = children[i];
1268
- if (child.tag === 'a') {
1269
- return child
1270
- }
1271
- if (child.children && (child = findAnchor(child.children))) {
1272
- return child
1273
- }
1274
- }
1275
- }
1276
- }
1277
-
1278
- var _Kdu;
1279
-
1280
- function install (Kdu) {
1281
- if (install.installed && _Kdu === Kdu) { return }
1282
- install.installed = true;
1283
-
1284
- _Kdu = Kdu;
1285
-
1286
- var isDef = function (v) { return v !== undefined; };
1287
-
1288
- var registerInstance = function (vm, callVal) {
1289
- var i = vm.$options._parentKnode;
1290
- if (isDef(i) && isDef(i = i.data) && isDef(i = i.registerRouteInstance)) {
1291
- i(vm, callVal);
1292
- }
1293
- };
1294
-
1295
- Kdu.mixin({
1296
- beforeCreate: function beforeCreate () {
1297
- if (isDef(this.$options.router)) {
1298
- this._routerRoot = this;
1299
- this._router = this.$options.router;
1300
- this._router.init(this);
1301
- Kdu.util.defineReactive(this, '_route', this._router.history.current);
1302
- } else {
1303
- this._routerRoot = (this.$parent && this.$parent._routerRoot) || this;
1304
- }
1305
- registerInstance(this, this);
1306
- },
1307
- destroyed: function destroyed () {
1308
- registerInstance(this);
1309
- }
1310
- });
1311
-
1312
- Object.defineProperty(Kdu.prototype, '$router', {
1313
- get: function get () { return this._routerRoot._router }
1314
- });
1315
-
1316
- Object.defineProperty(Kdu.prototype, '$route', {
1317
- get: function get () { return this._routerRoot._route }
1318
- });
1319
-
1320
- Kdu.component('RouterView', View);
1321
- Kdu.component('RouterLink', Link);
1322
-
1323
- var strats = Kdu.config.optionMergeStrategies;
1324
- // use the same hook merging strategy for route hooks
1325
- strats.beforeRouteEnter = strats.beforeRouteLeave = strats.beforeRouteUpdate = strats.created;
1326
- }
1327
-
1328
- /* */
1329
-
1330
- var inBrowser = typeof window !== 'undefined';
1331
-
1332
- /* */
1333
-
1334
- function createRouteMap (
1335
- routes,
1336
- oldPathList,
1337
- oldPathMap,
1338
- oldNameMap,
1339
- parentRoute
1340
- ) {
1341
- // the path list is used to control path matching priority
1342
- var pathList = oldPathList || [];
1343
- // $flow-disable-line
1344
- var pathMap = oldPathMap || Object.create(null);
1345
- // $flow-disable-line
1346
- var nameMap = oldNameMap || Object.create(null);
1347
-
1348
- routes.forEach(function (route) {
1349
- addRouteRecord(pathList, pathMap, nameMap, route, parentRoute);
1350
- });
1351
-
1352
- // ensure wildcard routes are always at the end
1353
- for (var i = 0, l = pathList.length; i < l; i++) {
1354
- if (pathList[i] === '*') {
1355
- pathList.push(pathList.splice(i, 1)[0]);
1356
- l--;
1357
- i--;
1358
- }
1359
- }
1360
-
1361
- if (process.env.NODE_ENV === 'development') {
1362
- // warn if routes do not include leading slashes
1363
- var found = pathList
1364
- // check for missing leading slash
1365
- .filter(function (path) { return path && path.charAt(0) !== '*' && path.charAt(0) !== '/'; });
1366
-
1367
- if (found.length > 0) {
1368
- var pathNames = found.map(function (path) { return ("- " + path); }).join('\n');
1369
- warn(false, ("Non-nested routes must include a leading slash character. Fix the following routes: \n" + pathNames));
1370
- }
1371
- }
1372
-
1373
- return {
1374
- pathList: pathList,
1375
- pathMap: pathMap,
1376
- nameMap: nameMap
1377
- }
1378
- }
1379
-
1380
- function addRouteRecord (
1381
- pathList,
1382
- pathMap,
1383
- nameMap,
1384
- route,
1385
- parent,
1386
- matchAs
1387
- ) {
1388
- var path = route.path;
1389
- var name = route.name;
1390
- if (process.env.NODE_ENV !== 'production') {
1391
- assert(path != null, "\"path\" is required in a route configuration.");
1392
- assert(
1393
- typeof route.component !== 'string',
1394
- "route config \"component\" for path: " + (String(
1395
- path || name
1396
- )) + " cannot be a " + "string id. Use an actual component instead."
1397
- );
1398
-
1399
- warn(
1400
- // eslint-disable-next-line no-control-regex
1401
- !/[^\u0000-\u007F]+/.test(path),
1402
- "Route with path \"" + path + "\" contains unencoded characters, make sure " +
1403
- "your path is correctly encoded before passing it to the router. Use " +
1404
- "encodeURI to encode static segments of your path."
1405
- );
1406
- }
1407
-
1408
- var pathToRegexpOptions =
1409
- route.pathToRegexpOptions || {};
1410
- var normalizedPath = normalizePath(path, parent, pathToRegexpOptions.strict);
1411
-
1412
- if (typeof route.caseSensitive === 'boolean') {
1413
- pathToRegexpOptions.sensitive = route.caseSensitive;
1414
- }
1415
-
1416
- var record = {
1417
- path: normalizedPath,
1418
- regex: compileRouteRegex(normalizedPath, pathToRegexpOptions),
1419
- components: route.components || { default: route.component },
1420
- alias: route.alias
1421
- ? typeof route.alias === 'string'
1422
- ? [route.alias]
1423
- : route.alias
1424
- : [],
1425
- instances: {},
1426
- enteredCbs: {},
1427
- name: name,
1428
- parent: parent,
1429
- matchAs: matchAs,
1430
- redirect: route.redirect,
1431
- beforeEnter: route.beforeEnter,
1432
- meta: route.meta || {},
1433
- props:
1434
- route.props == null
1435
- ? {}
1436
- : route.components
1437
- ? route.props
1438
- : { default: route.props }
1439
- };
1440
-
1441
- if (route.children) {
1442
- // Warn if route is named, does not redirect and has a default child route.
1443
- // If users navigate to this route by name, the default child will
1444
- // not be rendered (GH Issue #629)
1445
- if (process.env.NODE_ENV !== 'production') {
1446
- if (
1447
- route.name &&
1448
- !route.redirect &&
1449
- route.children.some(function (child) { return /^\/?$/.test(child.path); })
1450
- ) {
1451
- warn(
1452
- false,
1453
- "Named Route '" + (route.name) + "' has a default child route. " +
1454
- "When navigating to this named route (:to=\"{name: '" + (route.name) + "'}\"), " +
1455
- "the default child route will not be rendered. Remove the name from " +
1456
- "this route and use the name of the default child route for named " +
1457
- "links instead."
1458
- );
1459
- }
1460
- }
1461
- route.children.forEach(function (child) {
1462
- var childMatchAs = matchAs
1463
- ? cleanPath((matchAs + "/" + (child.path)))
1464
- : undefined;
1465
- addRouteRecord(pathList, pathMap, nameMap, child, record, childMatchAs);
1466
- });
1467
- }
1468
-
1469
- if (!pathMap[record.path]) {
1470
- pathList.push(record.path);
1471
- pathMap[record.path] = record;
1472
- }
1473
-
1474
- if (route.alias !== undefined) {
1475
- var aliases = Array.isArray(route.alias) ? route.alias : [route.alias];
1476
- for (var i = 0; i < aliases.length; ++i) {
1477
- var alias = aliases[i];
1478
- if (process.env.NODE_ENV !== 'production' && alias === path) {
1479
- warn(
1480
- false,
1481
- ("Found an alias with the same value as the path: \"" + path + "\". You have to remove that alias. It will be ignored in development.")
1482
- );
1483
- // skip in dev to make it work
1484
- continue
1485
- }
1486
-
1487
- var aliasRoute = {
1488
- path: alias,
1489
- children: route.children
1490
- };
1491
- addRouteRecord(
1492
- pathList,
1493
- pathMap,
1494
- nameMap,
1495
- aliasRoute,
1496
- parent,
1497
- record.path || '/' // matchAs
1498
- );
1499
- }
1500
- }
1501
-
1502
- if (name) {
1503
- if (!nameMap[name]) {
1504
- nameMap[name] = record;
1505
- } else if (process.env.NODE_ENV !== 'production' && !matchAs) {
1506
- warn(
1507
- false,
1508
- "Duplicate named routes definition: " +
1509
- "{ name: \"" + name + "\", path: \"" + (record.path) + "\" }"
1510
- );
1511
- }
1512
- }
1513
- }
1514
-
1515
- function compileRouteRegex (
1516
- path,
1517
- pathToRegexpOptions
1518
- ) {
1519
- var regex = pathToRegexp_1(path, [], pathToRegexpOptions);
1520
- if (process.env.NODE_ENV !== 'production') {
1521
- var keys = Object.create(null);
1522
- regex.keys.forEach(function (key) {
1523
- warn(
1524
- !keys[key.name],
1525
- ("Duplicate param keys in route with path: \"" + path + "\"")
1526
- );
1527
- keys[key.name] = true;
1528
- });
1529
- }
1530
- return regex
1531
- }
1532
-
1533
- function normalizePath (
1534
- path,
1535
- parent,
1536
- strict
1537
- ) {
1538
- if (!strict) { path = path.replace(/\/$/, ''); }
1539
- if (path[0] === '/') { return path }
1540
- if (parent == null) { return path }
1541
- return cleanPath(((parent.path) + "/" + path))
1542
- }
1543
-
1544
- /* */
1545
-
1546
-
1547
-
1548
- function createMatcher (
1549
- routes,
1550
- router
1551
- ) {
1552
- var ref = createRouteMap(routes);
1553
- var pathList = ref.pathList;
1554
- var pathMap = ref.pathMap;
1555
- var nameMap = ref.nameMap;
1556
-
1557
- function addRoutes (routes) {
1558
- createRouteMap(routes, pathList, pathMap, nameMap);
1559
- }
1560
-
1561
- function addRoute (parentOrRoute, route) {
1562
- var parent = (typeof parentOrRoute !== 'object') ? nameMap[parentOrRoute] : undefined;
1563
- // $flow-disable-line
1564
- createRouteMap([route || parentOrRoute], pathList, pathMap, nameMap, parent);
1565
-
1566
- // add aliases of parent
1567
- if (parent && parent.alias.length) {
1568
- createRouteMap(
1569
- // $flow-disable-line route is defined if parent is
1570
- parent.alias.map(function (alias) { return ({ path: alias, children: [route] }); }),
1571
- pathList,
1572
- pathMap,
1573
- nameMap,
1574
- parent
1575
- );
1576
- }
1577
- }
1578
-
1579
- function getRoutes () {
1580
- return pathList.map(function (path) { return pathMap[path]; })
1581
- }
1582
-
1583
- function match (
1584
- raw,
1585
- currentRoute,
1586
- redirectedFrom
1587
- ) {
1588
- var location = normalizeLocation(raw, currentRoute, false, router);
1589
- var name = location.name;
1590
-
1591
- if (name) {
1592
- var record = nameMap[name];
1593
- if (process.env.NODE_ENV !== 'production') {
1594
- warn(record, ("Route with name '" + name + "' does not exist"));
1595
- }
1596
- if (!record) { return _createRoute(null, location) }
1597
- var paramNames = record.regex.keys
1598
- .filter(function (key) { return !key.optional; })
1599
- .map(function (key) { return key.name; });
1600
-
1601
- if (typeof location.params !== 'object') {
1602
- location.params = {};
1603
- }
1604
-
1605
- if (currentRoute && typeof currentRoute.params === 'object') {
1606
- for (var key in currentRoute.params) {
1607
- if (!(key in location.params) && paramNames.indexOf(key) > -1) {
1608
- location.params[key] = currentRoute.params[key];
1609
- }
1610
- }
1611
- }
1612
-
1613
- location.path = fillParams(record.path, location.params, ("named route \"" + name + "\""));
1614
- return _createRoute(record, location, redirectedFrom)
1615
- } else if (location.path) {
1616
- location.params = {};
1617
- for (var i = 0; i < pathList.length; i++) {
1618
- var path = pathList[i];
1619
- var record$1 = pathMap[path];
1620
- if (matchRoute(record$1.regex, location.path, location.params)) {
1621
- return _createRoute(record$1, location, redirectedFrom)
1622
- }
1623
- }
1624
- }
1625
- // no match
1626
- return _createRoute(null, location)
1627
- }
1628
-
1629
- function redirect (
1630
- record,
1631
- location
1632
- ) {
1633
- var originalRedirect = record.redirect;
1634
- var redirect = typeof originalRedirect === 'function'
1635
- ? originalRedirect(createRoute(record, location, null, router))
1636
- : originalRedirect;
1637
-
1638
- if (typeof redirect === 'string') {
1639
- redirect = { path: redirect };
1640
- }
1641
-
1642
- if (!redirect || typeof redirect !== 'object') {
1643
- if (process.env.NODE_ENV !== 'production') {
1644
- warn(
1645
- false, ("invalid redirect option: " + (JSON.stringify(redirect)))
1646
- );
1647
- }
1648
- return _createRoute(null, location)
1649
- }
1650
-
1651
- var re = redirect;
1652
- var name = re.name;
1653
- var path = re.path;
1654
- var query = location.query;
1655
- var hash = location.hash;
1656
- var params = location.params;
1657
- query = re.hasOwnProperty('query') ? re.query : query;
1658
- hash = re.hasOwnProperty('hash') ? re.hash : hash;
1659
- params = re.hasOwnProperty('params') ? re.params : params;
1660
-
1661
- if (name) {
1662
- // resolved named direct
1663
- var targetRecord = nameMap[name];
1664
- if (process.env.NODE_ENV !== 'production') {
1665
- assert(targetRecord, ("redirect failed: named route \"" + name + "\" not found."));
1666
- }
1667
- return match({
1668
- _normalized: true,
1669
- name: name,
1670
- query: query,
1671
- hash: hash,
1672
- params: params
1673
- }, undefined, location)
1674
- } else if (path) {
1675
- // 1. resolve relative redirect
1676
- var rawPath = resolveRecordPath(path, record);
1677
- // 2. resolve params
1678
- var resolvedPath = fillParams(rawPath, params, ("redirect route with path \"" + rawPath + "\""));
1679
- // 3. rematch with existing query and hash
1680
- return match({
1681
- _normalized: true,
1682
- path: resolvedPath,
1683
- query: query,
1684
- hash: hash
1685
- }, undefined, location)
1686
- } else {
1687
- if (process.env.NODE_ENV !== 'production') {
1688
- warn(false, ("invalid redirect option: " + (JSON.stringify(redirect))));
1689
- }
1690
- return _createRoute(null, location)
1691
- }
1692
- }
1693
-
1694
- function alias (
1695
- record,
1696
- location,
1697
- matchAs
1698
- ) {
1699
- var aliasedPath = fillParams(matchAs, location.params, ("aliased route with path \"" + matchAs + "\""));
1700
- var aliasedMatch = match({
1701
- _normalized: true,
1702
- path: aliasedPath
1703
- });
1704
- if (aliasedMatch) {
1705
- var matched = aliasedMatch.matched;
1706
- var aliasedRecord = matched[matched.length - 1];
1707
- location.params = aliasedMatch.params;
1708
- return _createRoute(aliasedRecord, location)
1709
- }
1710
- return _createRoute(null, location)
1711
- }
1712
-
1713
- function _createRoute (
1714
- record,
1715
- location,
1716
- redirectedFrom
1717
- ) {
1718
- if (record && record.redirect) {
1719
- return redirect(record, redirectedFrom || location)
1720
- }
1721
- if (record && record.matchAs) {
1722
- return alias(record, location, record.matchAs)
1723
- }
1724
- return createRoute(record, location, redirectedFrom, router)
1725
- }
1726
-
1727
- return {
1728
- match: match,
1729
- addRoute: addRoute,
1730
- getRoutes: getRoutes,
1731
- addRoutes: addRoutes
1732
- }
1733
- }
1734
-
1735
- function matchRoute (
1736
- regex,
1737
- path,
1738
- params
1739
- ) {
1740
- var m = path.match(regex);
1741
-
1742
- if (!m) {
1743
- return false
1744
- } else if (!params) {
1745
- return true
1746
- }
1747
-
1748
- for (var i = 1, len = m.length; i < len; ++i) {
1749
- var key = regex.keys[i - 1];
1750
- if (key) {
1751
- // Fix #1994: using * with props: true generates a param named 0
1752
- params[key.name || 'pathMatch'] = typeof m[i] === 'string' ? decode(m[i]) : m[i];
1753
- }
1754
- }
1755
-
1756
- return true
1757
- }
1758
-
1759
- function resolveRecordPath (path, record) {
1760
- return resolvePath(path, record.parent ? record.parent.path : '/', true)
1761
- }
1762
-
1763
- /* */
1764
-
1765
- // use User Timing api (if present) for more accurate key precision
1766
- var Time =
1767
- inBrowser && window.performance && window.performance.now
1768
- ? window.performance
1769
- : Date;
1770
-
1771
- function genStateKey () {
1772
- return Time.now().toFixed(3)
1773
- }
1774
-
1775
- var _key = genStateKey();
1776
-
1777
- function getStateKey () {
1778
- return _key
1779
- }
1780
-
1781
- function setStateKey (key) {
1782
- return (_key = key)
1783
- }
1784
-
1785
- /* */
1786
-
1787
- var positionStore = Object.create(null);
1788
-
1789
- function setupScroll () {
1790
- // Prevent browser scroll behavior on History popstate
1791
- if ('scrollRestoration' in window.history) {
1792
- window.history.scrollRestoration = 'manual';
1793
- }
1794
- // Fix for #1585 for Firefox
1795
- // Fix for #2195 Add optional third attribute to workaround a bug in safari https://bugs.webkit.org/show_bug.cgi?id=182678
1796
- // Fix for #2774 Support for apps loaded from Windows file shares not mapped to network drives: replaced location.origin with
1797
- // window.location.protocol + '//' + window.location.host
1798
- // location.host contains the port and location.hostname doesn't
1799
- var protocolAndPath = window.location.protocol + '//' + window.location.host;
1800
- var absolutePath = window.location.href.replace(protocolAndPath, '');
1801
- // preserve existing history state as it could be overriden by the user
1802
- var stateCopy = extend({}, window.history.state);
1803
- stateCopy.key = getStateKey();
1804
- window.history.replaceState(stateCopy, '', absolutePath);
1805
- window.addEventListener('popstate', handlePopState);
1806
- return function () {
1807
- window.removeEventListener('popstate', handlePopState);
1808
- }
1809
- }
1810
-
1811
- function handleScroll (
1812
- router,
1813
- to,
1814
- from,
1815
- isPop
1816
- ) {
1817
- if (!router.app) {
1818
- return
1819
- }
1820
-
1821
- var behavior = router.options.scrollBehavior;
1822
- if (!behavior) {
1823
- return
1824
- }
1825
-
1826
- if (process.env.NODE_ENV !== 'production') {
1827
- assert(typeof behavior === 'function', "scrollBehavior must be a function");
1828
- }
1829
-
1830
- // wait until re-render finishes before scrolling
1831
- router.app.$nextTick(function () {
1832
- var position = getScrollPosition();
1833
- var shouldScroll = behavior.call(
1834
- router,
1835
- to,
1836
- from,
1837
- isPop ? position : null
1838
- );
1839
-
1840
- if (!shouldScroll) {
1841
- return
1842
- }
1843
-
1844
- if (typeof shouldScroll.then === 'function') {
1845
- shouldScroll
1846
- .then(function (shouldScroll) {
1847
- scrollToPosition((shouldScroll), position);
1848
- })
1849
- .catch(function (err) {
1850
- if (process.env.NODE_ENV !== 'production') {
1851
- assert(false, err.toString());
1852
- }
1853
- });
1854
- } else {
1855
- scrollToPosition(shouldScroll, position);
1856
- }
1857
- });
1858
- }
1859
-
1860
- function saveScrollPosition () {
1861
- var key = getStateKey();
1862
- if (key) {
1863
- positionStore[key] = {
1864
- x: window.pageXOffset,
1865
- y: window.pageYOffset
1866
- };
1867
- }
1868
- }
1869
-
1870
- function handlePopState (e) {
1871
- saveScrollPosition();
1872
- if (e.state && e.state.key) {
1873
- setStateKey(e.state.key);
1874
- }
1875
- }
1876
-
1877
- function getScrollPosition () {
1878
- var key = getStateKey();
1879
- if (key) {
1880
- return positionStore[key]
1881
- }
1882
- }
1883
-
1884
- function getElementPosition (el, offset) {
1885
- var docEl = document.documentElement;
1886
- var docRect = docEl.getBoundingClientRect();
1887
- var elRect = el.getBoundingClientRect();
1888
- return {
1889
- x: elRect.left - docRect.left - offset.x,
1890
- y: elRect.top - docRect.top - offset.y
1891
- }
1892
- }
1893
-
1894
- function isValidPosition (obj) {
1895
- return isNumber(obj.x) || isNumber(obj.y)
1896
- }
1897
-
1898
- function normalizePosition (obj) {
1899
- return {
1900
- x: isNumber(obj.x) ? obj.x : window.pageXOffset,
1901
- y: isNumber(obj.y) ? obj.y : window.pageYOffset
1902
- }
1903
- }
1904
-
1905
- function normalizeOffset (obj) {
1906
- return {
1907
- x: isNumber(obj.x) ? obj.x : 0,
1908
- y: isNumber(obj.y) ? obj.y : 0
1909
- }
1910
- }
1911
-
1912
- function isNumber (v) {
1913
- return typeof v === 'number'
1914
- }
1915
-
1916
- var hashStartsWithNumberRE = /^#\d/;
1917
-
1918
- function scrollToPosition (shouldScroll, position) {
1919
- var isObject = typeof shouldScroll === 'object';
1920
- if (isObject && typeof shouldScroll.selector === 'string') {
1921
- // getElementById would still fail if the selector contains a more complicated query like #main[data-attr]
1922
- // but at the same time, it doesn't make much sense to select an element with an id and an extra selector
1923
- var el = hashStartsWithNumberRE.test(shouldScroll.selector) // $flow-disable-line
1924
- ? document.getElementById(shouldScroll.selector.slice(1)) // $flow-disable-line
1925
- : document.querySelector(shouldScroll.selector);
1926
-
1927
- if (el) {
1928
- var offset =
1929
- shouldScroll.offset && typeof shouldScroll.offset === 'object'
1930
- ? shouldScroll.offset
1931
- : {};
1932
- offset = normalizeOffset(offset);
1933
- position = getElementPosition(el, offset);
1934
- } else if (isValidPosition(shouldScroll)) {
1935
- position = normalizePosition(shouldScroll);
1936
- }
1937
- } else if (isObject && isValidPosition(shouldScroll)) {
1938
- position = normalizePosition(shouldScroll);
1939
- }
1940
-
1941
- if (position) {
1942
- // $flow-disable-line
1943
- if ('scrollBehavior' in document.documentElement.style) {
1944
- window.scrollTo({
1945
- left: position.x,
1946
- top: position.y,
1947
- // $flow-disable-line
1948
- behavior: shouldScroll.behavior
1949
- });
1950
- } else {
1951
- window.scrollTo(position.x, position.y);
1952
- }
1953
- }
1954
- }
1955
-
1956
- /* */
1957
-
1958
- var supportsPushState =
1959
- inBrowser &&
1960
- (function () {
1961
- var ua = window.navigator.userAgent;
1962
-
1963
- if (
1964
- (ua.indexOf('Android 2.') !== -1 || ua.indexOf('Android 4.0') !== -1) &&
1965
- ua.indexOf('Mobile Safari') !== -1 &&
1966
- ua.indexOf('Chrome') === -1 &&
1967
- ua.indexOf('Windows Phone') === -1
1968
- ) {
1969
- return false
1970
- }
1971
-
1972
- return window.history && typeof window.history.pushState === 'function'
1973
- })();
1974
-
1975
- function pushState (url, replace) {
1976
- saveScrollPosition();
1977
- // try...catch the pushState call to get around Safari
1978
- // DOM Exception 18 where it limits to 100 pushState calls
1979
- var history = window.history;
1980
- try {
1981
- if (replace) {
1982
- // preserve existing history state as it could be overriden by the user
1983
- var stateCopy = extend({}, history.state);
1984
- stateCopy.key = getStateKey();
1985
- history.replaceState(stateCopy, '', url);
1986
- } else {
1987
- history.pushState({ key: setStateKey(genStateKey()) }, '', url);
1988
- }
1989
- } catch (e) {
1990
- window.location[replace ? 'replace' : 'assign'](url);
1991
- }
1992
- }
1993
-
1994
- function replaceState (url) {
1995
- pushState(url, true);
1996
- }
1997
-
1998
- /* */
1999
-
2000
- function runQueue (queue, fn, cb) {
2001
- var step = function (index) {
2002
- if (index >= queue.length) {
2003
- cb();
2004
- } else {
2005
- if (queue[index]) {
2006
- fn(queue[index], function () {
2007
- step(index + 1);
2008
- });
2009
- } else {
2010
- step(index + 1);
2011
- }
2012
- }
2013
- };
2014
- step(0);
2015
- }
2016
-
2017
- // When changing thing, also edit router.d.ts
2018
- var NavigationFailureType = {
2019
- redirected: 2,
2020
- aborted: 4,
2021
- cancelled: 8,
2022
- duplicated: 16
2023
- };
2024
-
2025
- function createNavigationRedirectedError (from, to) {
2026
- return createRouterError(
2027
- from,
2028
- to,
2029
- NavigationFailureType.redirected,
2030
- ("Redirected when going from \"" + (from.fullPath) + "\" to \"" + (stringifyRoute(
2031
- to
2032
- )) + "\" via a navigation guard.")
2033
- )
2034
- }
2035
-
2036
- function createNavigationDuplicatedError (from, to) {
2037
- var error = createRouterError(
2038
- from,
2039
- to,
2040
- NavigationFailureType.duplicated,
2041
- ("Avoided redundant navigation to current location: \"" + (from.fullPath) + "\".")
2042
- );
2043
- // backwards compatible with the first introduction of Errors
2044
- error.name = 'NavigationDuplicated';
2045
- return error
2046
- }
2047
-
2048
- function createNavigationCancelledError (from, to) {
2049
- return createRouterError(
2050
- from,
2051
- to,
2052
- NavigationFailureType.cancelled,
2053
- ("Navigation cancelled from \"" + (from.fullPath) + "\" to \"" + (to.fullPath) + "\" with a new navigation.")
2054
- )
2055
- }
2056
-
2057
- function createNavigationAbortedError (from, to) {
2058
- return createRouterError(
2059
- from,
2060
- to,
2061
- NavigationFailureType.aborted,
2062
- ("Navigation aborted from \"" + (from.fullPath) + "\" to \"" + (to.fullPath) + "\" via a navigation guard.")
2063
- )
2064
- }
2065
-
2066
- function createRouterError (from, to, type, message) {
2067
- var error = new Error(message);
2068
- error._isRouter = true;
2069
- error.from = from;
2070
- error.to = to;
2071
- error.type = type;
2072
-
2073
- return error
2074
- }
2075
-
2076
- var propertiesToLog = ['params', 'query', 'hash'];
2077
-
2078
- function stringifyRoute (to) {
2079
- if (typeof to === 'string') { return to }
2080
- if ('path' in to) { return to.path }
2081
- var location = {};
2082
- propertiesToLog.forEach(function (key) {
2083
- if (key in to) { location[key] = to[key]; }
2084
- });
2085
- return JSON.stringify(location, null, 2)
2086
- }
2087
-
2088
- function isError (err) {
2089
- return Object.prototype.toString.call(err).indexOf('Error') > -1
2090
- }
2091
-
2092
- function isNavigationFailure (err, errorType) {
2093
- return (
2094
- isError(err) &&
2095
- err._isRouter &&
2096
- (errorType == null || err.type === errorType)
2097
- )
2098
- }
2099
-
2100
- /* */
2101
-
2102
- function resolveAsyncComponents (matched) {
2103
- return function (to, from, next) {
2104
- var hasAsync = false;
2105
- var pending = 0;
2106
- var error = null;
2107
-
2108
- flatMapComponents(matched, function (def, _, match, key) {
2109
- // if it's a function and doesn't have cid attached,
2110
- // assume it's an async component resolve function.
2111
- // we are not using Kdu's default async resolving mechanism because
2112
- // we want to halt the navigation until the incoming component has been
2113
- // resolved.
2114
- if (typeof def === 'function' && def.cid === undefined) {
2115
- hasAsync = true;
2116
- pending++;
2117
-
2118
- var resolve = once(function (resolvedDef) {
2119
- if (isESModule(resolvedDef)) {
2120
- resolvedDef = resolvedDef.default;
2121
- }
2122
- // save resolved on async factory in case it's used elsewhere
2123
- def.resolved = typeof resolvedDef === 'function'
2124
- ? resolvedDef
2125
- : _Kdu.extend(resolvedDef);
2126
- match.components[key] = resolvedDef;
2127
- pending--;
2128
- if (pending <= 0) {
2129
- next();
2130
- }
2131
- });
2132
-
2133
- var reject = once(function (reason) {
2134
- var msg = "Failed to resolve async component " + key + ": " + reason;
2135
- process.env.NODE_ENV !== 'production' && warn(false, msg);
2136
- if (!error) {
2137
- error = isError(reason)
2138
- ? reason
2139
- : new Error(msg);
2140
- next(error);
2141
- }
2142
- });
2143
-
2144
- var res;
2145
- try {
2146
- res = def(resolve, reject);
2147
- } catch (e) {
2148
- reject(e);
2149
- }
2150
- if (res) {
2151
- if (typeof res.then === 'function') {
2152
- res.then(resolve, reject);
2153
- } else {
2154
- // new syntax in Kdu 2.3
2155
- var comp = res.component;
2156
- if (comp && typeof comp.then === 'function') {
2157
- comp.then(resolve, reject);
2158
- }
2159
- }
2160
- }
2161
- }
2162
- });
2163
-
2164
- if (!hasAsync) { next(); }
2165
- }
2166
- }
2167
-
2168
- function flatMapComponents (
2169
- matched,
2170
- fn
2171
- ) {
2172
- return flatten(matched.map(function (m) {
2173
- return Object.keys(m.components).map(function (key) { return fn(
2174
- m.components[key],
2175
- m.instances[key],
2176
- m, key
2177
- ); })
2178
- }))
2179
- }
2180
-
2181
- function flatten (arr) {
2182
- return Array.prototype.concat.apply([], arr)
2183
- }
2184
-
2185
- var hasSymbol =
2186
- typeof Symbol === 'function' &&
2187
- typeof Symbol.toStringTag === 'symbol';
2188
-
2189
- function isESModule (obj) {
2190
- return obj.__esModule || (hasSymbol && obj[Symbol.toStringTag] === 'Module')
2191
- }
2192
-
2193
- // in Webpack 2, require.ensure now also returns a Promise
2194
- // so the resolve/reject functions may get called an extra time
2195
- // if the user uses an arrow function shorthand that happens to
2196
- // return that Promise.
2197
- function once (fn) {
2198
- var called = false;
2199
- return function () {
2200
- var args = [], len = arguments.length;
2201
- while ( len-- ) args[ len ] = arguments[ len ];
2202
-
2203
- if (called) { return }
2204
- called = true;
2205
- return fn.apply(this, args)
2206
- }
2207
- }
2208
-
2209
- /* */
2210
-
2211
- var History = function History (router, base) {
2212
- this.router = router;
2213
- this.base = normalizeBase(base);
2214
- // start with a route object that stands for "nowhere"
2215
- this.current = START;
2216
- this.pending = null;
2217
- this.ready = false;
2218
- this.readyCbs = [];
2219
- this.readyErrorCbs = [];
2220
- this.errorCbs = [];
2221
- this.listeners = [];
2222
- };
2223
-
2224
- History.prototype.listen = function listen (cb) {
2225
- this.cb = cb;
2226
- };
2227
-
2228
- History.prototype.onReady = function onReady (cb, errorCb) {
2229
- if (this.ready) {
2230
- cb();
2231
- } else {
2232
- this.readyCbs.push(cb);
2233
- if (errorCb) {
2234
- this.readyErrorCbs.push(errorCb);
2235
- }
2236
- }
2237
- };
2238
-
2239
- History.prototype.onError = function onError (errorCb) {
2240
- this.errorCbs.push(errorCb);
2241
- };
2242
-
2243
- History.prototype.transitionTo = function transitionTo (
2244
- location,
2245
- onComplete,
2246
- onAbort
2247
- ) {
2248
- var this$1 = this;
2249
-
2250
- var route;
2251
- // catch redirect option
2252
- try {
2253
- route = this.router.match(location, this.current);
2254
- } catch (e) {
2255
- this.errorCbs.forEach(function (cb) {
2256
- cb(e);
2257
- });
2258
- // Exception should still be thrown
2259
- throw e
2260
- }
2261
- var prev = this.current;
2262
- this.confirmTransition(
2263
- route,
2264
- function () {
2265
- this$1.updateRoute(route);
2266
- onComplete && onComplete(route);
2267
- this$1.ensureURL();
2268
- this$1.router.afterHooks.forEach(function (hook) {
2269
- hook && hook(route, prev);
2270
- });
2271
-
2272
- // fire ready cbs once
2273
- if (!this$1.ready) {
2274
- this$1.ready = true;
2275
- this$1.readyCbs.forEach(function (cb) {
2276
- cb(route);
2277
- });
2278
- }
2279
- },
2280
- function (err) {
2281
- if (onAbort) {
2282
- onAbort(err);
2283
- }
2284
- if (err && !this$1.ready) {
2285
- // Initial redirection should not mark the history as ready yet
2286
- // because it's triggered by the redirection instead
2287
- if (!isNavigationFailure(err, NavigationFailureType.redirected) || prev !== START) {
2288
- this$1.ready = true;
2289
- this$1.readyErrorCbs.forEach(function (cb) {
2290
- cb(err);
2291
- });
2292
- }
2293
- }
2294
- }
2295
- );
2296
- };
2297
-
2298
- History.prototype.confirmTransition = function confirmTransition (route, onComplete, onAbort) {
2299
- var this$1 = this;
2300
-
2301
- var current = this.current;
2302
- this.pending = route;
2303
- var abort = function (err) {
2304
- // changed after adding errors
2305
- // before that change, redirect and aborted navigation would produce an err == null
2306
- if (!isNavigationFailure(err) && isError(err)) {
2307
- if (this$1.errorCbs.length) {
2308
- this$1.errorCbs.forEach(function (cb) {
2309
- cb(err);
2310
- });
2311
- } else {
2312
- if (process.env.NODE_ENV !== 'production') {
2313
- warn(false, 'uncaught error during route navigation:');
2314
- }
2315
- console.error(err);
2316
- }
2317
- }
2318
- onAbort && onAbort(err);
2319
- };
2320
- var lastRouteIndex = route.matched.length - 1;
2321
- var lastCurrentIndex = current.matched.length - 1;
2322
- if (
2323
- isSameRoute(route, current) &&
2324
- // in the case the route map has been dynamically appended to
2325
- lastRouteIndex === lastCurrentIndex &&
2326
- route.matched[lastRouteIndex] === current.matched[lastCurrentIndex]
2327
- ) {
2328
- this.ensureURL();
2329
- if (route.hash) {
2330
- handleScroll(this.router, current, route, false);
2331
- }
2332
- return abort(createNavigationDuplicatedError(current, route))
2333
- }
2334
-
2335
- var ref = resolveQueue(
2336
- this.current.matched,
2337
- route.matched
2338
- );
2339
- var updated = ref.updated;
2340
- var deactivated = ref.deactivated;
2341
- var activated = ref.activated;
2342
-
2343
- var queue = [].concat(
2344
- // in-component leave guards
2345
- extractLeaveGuards(deactivated),
2346
- // global before hooks
2347
- this.router.beforeHooks,
2348
- // in-component update hooks
2349
- extractUpdateHooks(updated),
2350
- // in-config enter guards
2351
- activated.map(function (m) { return m.beforeEnter; }),
2352
- // async components
2353
- resolveAsyncComponents(activated)
2354
- );
2355
-
2356
- var iterator = function (hook, next) {
2357
- if (this$1.pending !== route) {
2358
- return abort(createNavigationCancelledError(current, route))
2359
- }
2360
- try {
2361
- hook(route, current, function (to) {
2362
- if (to === false) {
2363
- // next(false) -> abort navigation, ensure current URL
2364
- this$1.ensureURL(true);
2365
- abort(createNavigationAbortedError(current, route));
2366
- } else if (isError(to)) {
2367
- this$1.ensureURL(true);
2368
- abort(to);
2369
- } else if (
2370
- typeof to === 'string' ||
2371
- (typeof to === 'object' &&
2372
- (typeof to.path === 'string' || typeof to.name === 'string'))
2373
- ) {
2374
- // next('/') or next({ path: '/' }) -> redirect
2375
- abort(createNavigationRedirectedError(current, route));
2376
- if (typeof to === 'object' && to.replace) {
2377
- this$1.replace(to);
2378
- } else {
2379
- this$1.push(to);
2380
- }
2381
- } else {
2382
- // confirm transition and pass on the value
2383
- next(to);
2384
- }
2385
- });
2386
- } catch (e) {
2387
- abort(e);
2388
- }
2389
- };
2390
-
2391
- runQueue(queue, iterator, function () {
2392
- // wait until async components are resolved before
2393
- // extracting in-component enter guards
2394
- var enterGuards = extractEnterGuards(activated);
2395
- var queue = enterGuards.concat(this$1.router.resolveHooks);
2396
- runQueue(queue, iterator, function () {
2397
- if (this$1.pending !== route) {
2398
- return abort(createNavigationCancelledError(current, route))
2399
- }
2400
- this$1.pending = null;
2401
- onComplete(route);
2402
- if (this$1.router.app) {
2403
- this$1.router.app.$nextTick(function () {
2404
- handleRouteEntered(route);
2405
- });
2406
- }
2407
- });
2408
- });
2409
- };
2410
-
2411
- History.prototype.updateRoute = function updateRoute (route) {
2412
- this.current = route;
2413
- this.cb && this.cb(route);
2414
- };
2415
-
2416
- History.prototype.setupListeners = function setupListeners () {
2417
- // Default implementation is empty
2418
- };
2419
-
2420
- History.prototype.teardown = function teardown () {
2421
- // clean up event listeners
2422
- this.listeners.forEach(function (cleanupListener) {
2423
- cleanupListener();
2424
- });
2425
- this.listeners = [];
2426
-
2427
- // reset current history route
2428
- this.current = START;
2429
- this.pending = null;
2430
- };
2431
-
2432
- function normalizeBase (base) {
2433
- if (!base) {
2434
- if (inBrowser) {
2435
- // respect <base> tag
2436
- var baseEl = document.querySelector('base');
2437
- base = (baseEl && baseEl.getAttribute('href')) || '/';
2438
- // strip full URL origin
2439
- base = base.replace(/^https?:\/\/[^\/]+/, '');
2440
- } else {
2441
- base = '/';
2442
- }
2443
- }
2444
- // make sure there's the starting slash
2445
- if (base.charAt(0) !== '/') {
2446
- base = '/' + base;
2447
- }
2448
- // remove trailing slash
2449
- return base.replace(/\/$/, '')
2450
- }
2451
-
2452
- function resolveQueue (
2453
- current,
2454
- next
2455
- ) {
2456
- var i;
2457
- var max = Math.max(current.length, next.length);
2458
- for (i = 0; i < max; i++) {
2459
- if (current[i] !== next[i]) {
2460
- break
2461
- }
2462
- }
2463
- return {
2464
- updated: next.slice(0, i),
2465
- activated: next.slice(i),
2466
- deactivated: current.slice(i)
2467
- }
2468
- }
2469
-
2470
- function extractGuards (
2471
- records,
2472
- name,
2473
- bind,
2474
- reverse
2475
- ) {
2476
- var guards = flatMapComponents(records, function (def, instance, match, key) {
2477
- var guard = extractGuard(def, name);
2478
- if (guard) {
2479
- return Array.isArray(guard)
2480
- ? guard.map(function (guard) { return bind(guard, instance, match, key); })
2481
- : bind(guard, instance, match, key)
2482
- }
2483
- });
2484
- return flatten(reverse ? guards.reverse() : guards)
2485
- }
2486
-
2487
- function extractGuard (
2488
- def,
2489
- key
2490
- ) {
2491
- if (typeof def !== 'function') {
2492
- // extend now so that global mixins are applied.
2493
- def = _Kdu.extend(def);
2494
- }
2495
- return def.options[key]
2496
- }
2497
-
2498
- function extractLeaveGuards (deactivated) {
2499
- return extractGuards(deactivated, 'beforeRouteLeave', bindGuard, true)
2500
- }
2501
-
2502
- function extractUpdateHooks (updated) {
2503
- return extractGuards(updated, 'beforeRouteUpdate', bindGuard)
2504
- }
2505
-
2506
- function bindGuard (guard, instance) {
2507
- if (instance) {
2508
- return function boundRouteGuard () {
2509
- return guard.apply(instance, arguments)
2510
- }
2511
- }
2512
- }
2513
-
2514
- function extractEnterGuards (
2515
- activated
2516
- ) {
2517
- return extractGuards(
2518
- activated,
2519
- 'beforeRouteEnter',
2520
- function (guard, _, match, key) {
2521
- return bindEnterGuard(guard, match, key)
2522
- }
2523
- )
2524
- }
2525
-
2526
- function bindEnterGuard (
2527
- guard,
2528
- match,
2529
- key
2530
- ) {
2531
- return function routeEnterGuard (to, from, next) {
2532
- return guard(to, from, function (cb) {
2533
- if (typeof cb === 'function') {
2534
- if (!match.enteredCbs[key]) {
2535
- match.enteredCbs[key] = [];
2536
- }
2537
- match.enteredCbs[key].push(cb);
2538
- }
2539
- next(cb);
2540
- })
2541
- }
2542
- }
2543
-
2544
- /* */
2545
-
2546
- var HTML5History = /*@__PURE__*/(function (History) {
2547
- function HTML5History (router, base) {
2548
- History.call(this, router, base);
2549
-
2550
- this._startLocation = getLocation(this.base);
2551
- }
2552
-
2553
- if ( History ) HTML5History.__proto__ = History;
2554
- HTML5History.prototype = Object.create( History && History.prototype );
2555
- HTML5History.prototype.constructor = HTML5History;
2556
-
2557
- HTML5History.prototype.setupListeners = function setupListeners () {
2558
- var this$1 = this;
2559
-
2560
- if (this.listeners.length > 0) {
2561
- return
2562
- }
2563
-
2564
- var router = this.router;
2565
- var expectScroll = router.options.scrollBehavior;
2566
- var supportsScroll = supportsPushState && expectScroll;
2567
-
2568
- if (supportsScroll) {
2569
- this.listeners.push(setupScroll());
2570
- }
2571
-
2572
- var handleRoutingEvent = function () {
2573
- var current = this$1.current;
2574
-
2575
- // Avoiding first `popstate` event dispatched in some browsers but first
2576
- // history route not updated since async guard at the same time.
2577
- var location = getLocation(this$1.base);
2578
- if (this$1.current === START && location === this$1._startLocation) {
2579
- return
2580
- }
2581
-
2582
- this$1.transitionTo(location, function (route) {
2583
- if (supportsScroll) {
2584
- handleScroll(router, route, current, true);
2585
- }
2586
- });
2587
- };
2588
- window.addEventListener('popstate', handleRoutingEvent);
2589
- this.listeners.push(function () {
2590
- window.removeEventListener('popstate', handleRoutingEvent);
2591
- });
2592
- };
2593
-
2594
- HTML5History.prototype.go = function go (n) {
2595
- window.history.go(n);
2596
- };
2597
-
2598
- HTML5History.prototype.push = function push (location, onComplete, onAbort) {
2599
- var this$1 = this;
2600
-
2601
- var ref = this;
2602
- var fromRoute = ref.current;
2603
- this.transitionTo(location, function (route) {
2604
- pushState(cleanPath(this$1.base + route.fullPath));
2605
- handleScroll(this$1.router, route, fromRoute, false);
2606
- onComplete && onComplete(route);
2607
- }, onAbort);
2608
- };
2609
-
2610
- HTML5History.prototype.replace = function replace (location, onComplete, onAbort) {
2611
- var this$1 = this;
2612
-
2613
- var ref = this;
2614
- var fromRoute = ref.current;
2615
- this.transitionTo(location, function (route) {
2616
- replaceState(cleanPath(this$1.base + route.fullPath));
2617
- handleScroll(this$1.router, route, fromRoute, false);
2618
- onComplete && onComplete(route);
2619
- }, onAbort);
2620
- };
2621
-
2622
- HTML5History.prototype.ensureURL = function ensureURL (push) {
2623
- if (getLocation(this.base) !== this.current.fullPath) {
2624
- var current = cleanPath(this.base + this.current.fullPath);
2625
- push ? pushState(current) : replaceState(current);
2626
- }
2627
- };
2628
-
2629
- HTML5History.prototype.getCurrentLocation = function getCurrentLocation () {
2630
- return getLocation(this.base)
2631
- };
2632
-
2633
- return HTML5History;
2634
- }(History));
2635
-
2636
- function getLocation (base) {
2637
- var path = window.location.pathname;
2638
- var pathLowerCase = path.toLowerCase();
2639
- var baseLowerCase = base.toLowerCase();
2640
- // base="/a" shouldn't turn path="/app" into "/a/pp"
2641
- // so we ensure the trailing slash in the base
2642
- if (base && ((pathLowerCase === baseLowerCase) ||
2643
- (pathLowerCase.indexOf(cleanPath(baseLowerCase + '/')) === 0))) {
2644
- path = path.slice(base.length);
2645
- }
2646
- return (path || '/') + window.location.search + window.location.hash
2647
- }
2648
-
2649
- /* */
2650
-
2651
- var HashHistory = /*@__PURE__*/(function (History) {
2652
- function HashHistory (router, base, fallback) {
2653
- History.call(this, router, base);
2654
- // check history fallback deeplinking
2655
- if (fallback && checkFallback(this.base)) {
2656
- return
2657
- }
2658
- ensureSlash();
2659
- }
2660
-
2661
- if ( History ) HashHistory.__proto__ = History;
2662
- HashHistory.prototype = Object.create( History && History.prototype );
2663
- HashHistory.prototype.constructor = HashHistory;
2664
-
2665
- // this is delayed until the app mounts
2666
- // to avoid the hashchange listener being fired too early
2667
- HashHistory.prototype.setupListeners = function setupListeners () {
2668
- var this$1 = this;
2669
-
2670
- if (this.listeners.length > 0) {
2671
- return
2672
- }
2673
-
2674
- var router = this.router;
2675
- var expectScroll = router.options.scrollBehavior;
2676
- var supportsScroll = supportsPushState && expectScroll;
2677
-
2678
- if (supportsScroll) {
2679
- this.listeners.push(setupScroll());
2680
- }
2681
-
2682
- var handleRoutingEvent = function () {
2683
- var current = this$1.current;
2684
- if (!ensureSlash()) {
2685
- return
2686
- }
2687
- this$1.transitionTo(getHash(), function (route) {
2688
- if (supportsScroll) {
2689
- handleScroll(this$1.router, route, current, true);
2690
- }
2691
- if (!supportsPushState) {
2692
- replaceHash(route.fullPath);
2693
- }
2694
- });
2695
- };
2696
- var eventType = supportsPushState ? 'popstate' : 'hashchange';
2697
- window.addEventListener(
2698
- eventType,
2699
- handleRoutingEvent
2700
- );
2701
- this.listeners.push(function () {
2702
- window.removeEventListener(eventType, handleRoutingEvent);
2703
- });
2704
- };
2705
-
2706
- HashHistory.prototype.push = function push (location, onComplete, onAbort) {
2707
- var this$1 = this;
2708
-
2709
- var ref = this;
2710
- var fromRoute = ref.current;
2711
- this.transitionTo(
2712
- location,
2713
- function (route) {
2714
- pushHash(route.fullPath);
2715
- handleScroll(this$1.router, route, fromRoute, false);
2716
- onComplete && onComplete(route);
2717
- },
2718
- onAbort
2719
- );
2720
- };
2721
-
2722
- HashHistory.prototype.replace = function replace (location, onComplete, onAbort) {
2723
- var this$1 = this;
2724
-
2725
- var ref = this;
2726
- var fromRoute = ref.current;
2727
- this.transitionTo(
2728
- location,
2729
- function (route) {
2730
- replaceHash(route.fullPath);
2731
- handleScroll(this$1.router, route, fromRoute, false);
2732
- onComplete && onComplete(route);
2733
- },
2734
- onAbort
2735
- );
2736
- };
2737
-
2738
- HashHistory.prototype.go = function go (n) {
2739
- window.history.go(n);
2740
- };
2741
-
2742
- HashHistory.prototype.ensureURL = function ensureURL (push) {
2743
- var current = this.current.fullPath;
2744
- if (getHash() !== current) {
2745
- push ? pushHash(current) : replaceHash(current);
2746
- }
2747
- };
2748
-
2749
- HashHistory.prototype.getCurrentLocation = function getCurrentLocation () {
2750
- return getHash()
2751
- };
2752
-
2753
- return HashHistory;
2754
- }(History));
2755
-
2756
- function checkFallback (base) {
2757
- var location = getLocation(base);
2758
- if (!/^\/#/.test(location)) {
2759
- window.location.replace(cleanPath(base + '/#' + location));
2760
- return true
2761
- }
2762
- }
2763
-
2764
- function ensureSlash () {
2765
- var path = getHash();
2766
- if (path.charAt(0) === '/') {
2767
- return true
2768
- }
2769
- replaceHash('/' + path);
2770
- return false
2771
- }
2772
-
2773
- function getHash () {
2774
- // We can't use window.location.hash here because it's not
2775
- // consistent across browsers - Firefox will pre-decode it!
2776
- var href = window.location.href;
2777
- var index = href.indexOf('#');
2778
- // empty path
2779
- if (index < 0) { return '' }
2780
-
2781
- href = href.slice(index + 1);
2782
-
2783
- return href
2784
- }
2785
-
2786
- function getUrl (path) {
2787
- var href = window.location.href;
2788
- var i = href.indexOf('#');
2789
- var base = i >= 0 ? href.slice(0, i) : href;
2790
- return (base + "#" + path)
2791
- }
2792
-
2793
- function pushHash (path) {
2794
- if (supportsPushState) {
2795
- pushState(getUrl(path));
2796
- } else {
2797
- window.location.hash = path;
2798
- }
2799
- }
2800
-
2801
- function replaceHash (path) {
2802
- if (supportsPushState) {
2803
- replaceState(getUrl(path));
2804
- } else {
2805
- window.location.replace(getUrl(path));
2806
- }
2807
- }
2808
-
2809
- /* */
2810
-
2811
- var AbstractHistory = /*@__PURE__*/(function (History) {
2812
- function AbstractHistory (router, base) {
2813
- History.call(this, router, base);
2814
- this.stack = [];
2815
- this.index = -1;
2816
- }
2817
-
2818
- if ( History ) AbstractHistory.__proto__ = History;
2819
- AbstractHistory.prototype = Object.create( History && History.prototype );
2820
- AbstractHistory.prototype.constructor = AbstractHistory;
2821
-
2822
- AbstractHistory.prototype.push = function push (location, onComplete, onAbort) {
2823
- var this$1 = this;
2824
-
2825
- this.transitionTo(
2826
- location,
2827
- function (route) {
2828
- this$1.stack = this$1.stack.slice(0, this$1.index + 1).concat(route);
2829
- this$1.index++;
2830
- onComplete && onComplete(route);
2831
- },
2832
- onAbort
2833
- );
2834
- };
2835
-
2836
- AbstractHistory.prototype.replace = function replace (location, onComplete, onAbort) {
2837
- var this$1 = this;
2838
-
2839
- this.transitionTo(
2840
- location,
2841
- function (route) {
2842
- this$1.stack = this$1.stack.slice(0, this$1.index).concat(route);
2843
- onComplete && onComplete(route);
2844
- },
2845
- onAbort
2846
- );
2847
- };
2848
-
2849
- AbstractHistory.prototype.go = function go (n) {
2850
- var this$1 = this;
2851
-
2852
- var targetIndex = this.index + n;
2853
- if (targetIndex < 0 || targetIndex >= this.stack.length) {
2854
- return
2855
- }
2856
- var route = this.stack[targetIndex];
2857
- this.confirmTransition(
2858
- route,
2859
- function () {
2860
- var prev = this$1.current;
2861
- this$1.index = targetIndex;
2862
- this$1.updateRoute(route);
2863
- this$1.router.afterHooks.forEach(function (hook) {
2864
- hook && hook(route, prev);
2865
- });
2866
- },
2867
- function (err) {
2868
- if (isNavigationFailure(err, NavigationFailureType.duplicated)) {
2869
- this$1.index = targetIndex;
2870
- }
2871
- }
2872
- );
2873
- };
2874
-
2875
- AbstractHistory.prototype.getCurrentLocation = function getCurrentLocation () {
2876
- var current = this.stack[this.stack.length - 1];
2877
- return current ? current.fullPath : '/'
2878
- };
2879
-
2880
- AbstractHistory.prototype.ensureURL = function ensureURL () {
2881
- // noop
2882
- };
2883
-
2884
- return AbstractHistory;
2885
- }(History));
2886
-
2887
- /* */
2888
-
2889
- var KduRouter = function KduRouter (options) {
2890
- if ( options === void 0 ) options = {};
2891
-
2892
- if (process.env.NODE_ENV !== 'production') {
2893
- warn(this instanceof KduRouter, "Router must be called with the new operator.");
2894
- }
2895
- this.app = null;
2896
- this.apps = [];
2897
- this.options = options;
2898
- this.beforeHooks = [];
2899
- this.resolveHooks = [];
2900
- this.afterHooks = [];
2901
- this.matcher = createMatcher(options.routes || [], this);
2902
-
2903
- var mode = options.mode || 'hash';
2904
- this.fallback =
2905
- mode === 'history' && !supportsPushState && options.fallback !== false;
2906
- if (this.fallback) {
2907
- mode = 'hash';
2908
- }
2909
- if (!inBrowser) {
2910
- mode = 'abstract';
2911
- }
2912
- this.mode = mode;
2913
-
2914
- switch (mode) {
2915
- case 'history':
2916
- this.history = new HTML5History(this, options.base);
2917
- break
2918
- case 'hash':
2919
- this.history = new HashHistory(this, options.base, this.fallback);
2920
- break
2921
- case 'abstract':
2922
- this.history = new AbstractHistory(this, options.base);
2923
- break
2924
- default:
2925
- if (process.env.NODE_ENV !== 'production') {
2926
- assert(false, ("invalid mode: " + mode));
2927
- }
2928
- }
2929
- };
2930
-
2931
- var prototypeAccessors = { currentRoute: { configurable: true } };
2932
-
2933
- KduRouter.prototype.match = function match (raw, current, redirectedFrom) {
2934
- return this.matcher.match(raw, current, redirectedFrom)
2935
- };
2936
-
2937
- prototypeAccessors.currentRoute.get = function () {
2938
- return this.history && this.history.current
2939
- };
2940
-
2941
- KduRouter.prototype.init = function init (app /* Kdu component instance */) {
2942
- var this$1 = this;
2943
-
2944
- process.env.NODE_ENV !== 'production' &&
2945
- assert(
2946
- install.installed,
2947
- "not installed. Make sure to call `Kdu.use(KduRouter)` " +
2948
- "before creating root instance."
2949
- );
2950
-
2951
- this.apps.push(app);
2952
-
2953
- // set up app destroyed handler
2954
- app.$once('hook:destroyed', function () {
2955
- // clean out app from this.apps array once destroyed
2956
- var index = this$1.apps.indexOf(app);
2957
- if (index > -1) { this$1.apps.splice(index, 1); }
2958
- // ensure we still have a main app or null if no apps
2959
- // we do not release the router so it can be reused
2960
- if (this$1.app === app) { this$1.app = this$1.apps[0] || null; }
2961
-
2962
- if (!this$1.app) { this$1.history.teardown(); }
2963
- });
2964
-
2965
- // main app previously initialized
2966
- // return as we don't need to set up new history listener
2967
- if (this.app) {
2968
- return
2969
- }
2970
-
2971
- this.app = app;
2972
-
2973
- var history = this.history;
2974
-
2975
- if (history instanceof HTML5History || history instanceof HashHistory) {
2976
- var handleInitialScroll = function (routeOrError) {
2977
- var from = history.current;
2978
- var expectScroll = this$1.options.scrollBehavior;
2979
- var supportsScroll = supportsPushState && expectScroll;
2980
-
2981
- if (supportsScroll && 'fullPath' in routeOrError) {
2982
- handleScroll(this$1, routeOrError, from, false);
2983
- }
2984
- };
2985
- var setupListeners = function (routeOrError) {
2986
- history.setupListeners();
2987
- handleInitialScroll(routeOrError);
2988
- };
2989
- history.transitionTo(
2990
- history.getCurrentLocation(),
2991
- setupListeners,
2992
- setupListeners
2993
- );
2994
- }
2995
-
2996
- history.listen(function (route) {
2997
- this$1.apps.forEach(function (app) {
2998
- app._route = route;
2999
- });
3000
- });
3001
- };
3002
-
3003
- KduRouter.prototype.beforeEach = function beforeEach (fn) {
3004
- return registerHook(this.beforeHooks, fn)
3005
- };
3006
-
3007
- KduRouter.prototype.beforeResolve = function beforeResolve (fn) {
3008
- return registerHook(this.resolveHooks, fn)
3009
- };
3010
-
3011
- KduRouter.prototype.afterEach = function afterEach (fn) {
3012
- return registerHook(this.afterHooks, fn)
3013
- };
3014
-
3015
- KduRouter.prototype.onReady = function onReady (cb, errorCb) {
3016
- this.history.onReady(cb, errorCb);
3017
- };
3018
-
3019
- KduRouter.prototype.onError = function onError (errorCb) {
3020
- this.history.onError(errorCb);
3021
- };
3022
-
3023
- KduRouter.prototype.push = function push (location, onComplete, onAbort) {
3024
- var this$1 = this;
3025
-
3026
- // $flow-disable-line
3027
- if (!onComplete && !onAbort && typeof Promise !== 'undefined') {
3028
- return new Promise(function (resolve, reject) {
3029
- this$1.history.push(location, resolve, reject);
3030
- })
3031
- } else {
3032
- this.history.push(location, onComplete, onAbort);
3033
- }
3034
- };
3035
-
3036
- KduRouter.prototype.replace = function replace (location, onComplete, onAbort) {
3037
- var this$1 = this;
3038
-
3039
- // $flow-disable-line
3040
- if (!onComplete && !onAbort && typeof Promise !== 'undefined') {
3041
- return new Promise(function (resolve, reject) {
3042
- this$1.history.replace(location, resolve, reject);
3043
- })
3044
- } else {
3045
- this.history.replace(location, onComplete, onAbort);
3046
- }
3047
- };
3048
-
3049
- KduRouter.prototype.go = function go (n) {
3050
- this.history.go(n);
3051
- };
3052
-
3053
- KduRouter.prototype.back = function back () {
3054
- this.go(-1);
3055
- };
3056
-
3057
- KduRouter.prototype.forward = function forward () {
3058
- this.go(1);
3059
- };
3060
-
3061
- KduRouter.prototype.getMatchedComponents = function getMatchedComponents (to) {
3062
- var route = to
3063
- ? to.matched
3064
- ? to
3065
- : this.resolve(to).route
3066
- : this.currentRoute;
3067
- if (!route) {
3068
- return []
3069
- }
3070
- return [].concat.apply(
3071
- [],
3072
- route.matched.map(function (m) {
3073
- return Object.keys(m.components).map(function (key) {
3074
- return m.components[key]
3075
- })
3076
- })
3077
- )
3078
- };
3079
-
3080
- KduRouter.prototype.resolve = function resolve (
3081
- to,
3082
- current,
3083
- append
3084
- ) {
3085
- current = current || this.history.current;
3086
- var location = normalizeLocation(to, current, append, this);
3087
- var route = this.match(location, current);
3088
- var fullPath = route.redirectedFrom || route.fullPath;
3089
- var base = this.history.base;
3090
- var href = createHref(base, fullPath, this.mode);
3091
- return {
3092
- location: location,
3093
- route: route,
3094
- href: href,
3095
- // for backwards compat
3096
- normalizedTo: location,
3097
- resolved: route
3098
- }
3099
- };
3100
-
3101
- KduRouter.prototype.getRoutes = function getRoutes () {
3102
- return this.matcher.getRoutes()
3103
- };
3104
-
3105
- KduRouter.prototype.addRoute = function addRoute (parentOrRoute, route) {
3106
- this.matcher.addRoute(parentOrRoute, route);
3107
- if (this.history.current !== START) {
3108
- this.history.transitionTo(this.history.getCurrentLocation());
3109
- }
3110
- };
3111
-
3112
- KduRouter.prototype.addRoutes = function addRoutes (routes) {
3113
- if (process.env.NODE_ENV !== 'production') {
3114
- warn(false, 'router.addRoutes() is deprecated and has been removed in Kdu Router 4. Use router.addRoute() instead.');
3115
- }
3116
- this.matcher.addRoutes(routes);
3117
- if (this.history.current !== START) {
3118
- this.history.transitionTo(this.history.getCurrentLocation());
3119
- }
3120
- };
3121
-
3122
- Object.defineProperties( KduRouter.prototype, prototypeAccessors );
3123
-
3124
- function registerHook (list, fn) {
3125
- list.push(fn);
3126
- return function () {
3127
- var i = list.indexOf(fn);
3128
- if (i > -1) { list.splice(i, 1); }
3129
- }
3130
- }
3131
-
3132
- function createHref (base, fullPath, mode) {
3133
- var path = mode === 'hash' ? '#' + fullPath : fullPath;
3134
- return base ? cleanPath(base + '/' + path) : path
3135
- }
3136
-
3137
- KduRouter.install = install;
3138
- KduRouter.version = '3.5.4';
3139
- KduRouter.isNavigationFailure = isNavigationFailure;
3140
- KduRouter.NavigationFailureType = NavigationFailureType;
3141
- KduRouter.START_LOCATION = START;
3142
-
3143
- if (inBrowser && window.Kdu) {
3144
- window.Kdu.use(KduRouter);
3145
- }
3146
-
3147
- module.exports = KduRouter;