kdu-router 3.4.0-beta.0 → 3.6.0

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 (49) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +11 -9
  3. package/dist/composables.js +253 -0
  4. package/dist/composables.mjs +244 -0
  5. package/dist/kdu-router.common.js +2682 -2572
  6. package/dist/kdu-router.esm.browser.js +2677 -2563
  7. package/dist/kdu-router.esm.browser.min.js +5 -5
  8. package/dist/kdu-router.esm.js +2685 -2572
  9. package/dist/kdu-router.js +2682 -2573
  10. package/dist/kdu-router.min.js +5 -5
  11. package/ketur/attributes.json +38 -38
  12. package/ketur/tags.json +20 -20
  13. package/package.json +115 -111
  14. package/src/components/link.js +224 -197
  15. package/src/components/view.js +155 -149
  16. package/src/composables/globals.js +34 -0
  17. package/src/composables/guards.js +68 -0
  18. package/src/composables/index.js +3 -0
  19. package/src/composables/useLink.js +113 -0
  20. package/src/composables/utils.js +11 -0
  21. package/src/create-matcher.js +226 -200
  22. package/src/create-route-map.js +220 -205
  23. package/src/entries/cjs.js +3 -0
  24. package/src/entries/esm.js +12 -0
  25. package/src/history/abstract.js +72 -68
  26. package/src/history/base.js +379 -400
  27. package/src/history/hash.js +152 -163
  28. package/src/history/html5.js +99 -94
  29. package/src/index.js +3 -277
  30. package/src/install.js +52 -52
  31. package/src/router.js +293 -0
  32. package/src/util/async.js +18 -18
  33. package/src/util/dom.js +3 -3
  34. package/src/util/errors.js +86 -85
  35. package/src/util/location.js +69 -69
  36. package/src/util/misc.js +6 -6
  37. package/src/util/params.js +37 -37
  38. package/src/util/path.js +74 -74
  39. package/src/util/push-state.js +46 -46
  40. package/src/util/query.js +113 -96
  41. package/src/util/resolve-components.js +109 -109
  42. package/src/util/route.js +151 -132
  43. package/src/util/scroll.js +175 -165
  44. package/src/util/state-key.js +22 -22
  45. package/src/util/warn.js +14 -14
  46. package/types/composables.d.ts +53 -0
  47. package/types/index.d.ts +25 -17
  48. package/types/kdu.d.ts +22 -22
  49. package/types/router.d.ts +564 -170
package/src/util/query.js CHANGED
@@ -1,96 +1,113 @@
1
- /* @flow */
2
-
3
- import { warn } from './warn'
4
-
5
- const encodeReserveRE = /[!'()*]/g
6
- const encodeReserveReplacer = c => '%' + c.charCodeAt(0).toString(16)
7
- const commaRE = /%2C/g
8
-
9
- // fixed encodeURIComponent which is more conformant to RFC3986:
10
- // - escapes [!'()*]
11
- // - preserve commas
12
- const encode = str => encodeURIComponent(str)
13
- .replace(encodeReserveRE, encodeReserveReplacer)
14
- .replace(commaRE, ',')
15
-
16
- const decode = decodeURIComponent
17
-
18
- export function resolveQuery (
19
- query: ?string,
20
- extraQuery: Dictionary<string> = {},
21
- _parseQuery: ?Function
22
- ): Dictionary<string> {
23
- const parse = _parseQuery || parseQuery
24
- let parsedQuery
25
- try {
26
- parsedQuery = parse(query || '')
27
- } catch (e) {
28
- process.env.NODE_ENV !== 'production' && warn(false, e.message)
29
- parsedQuery = {}
30
- }
31
- for (const key in extraQuery) {
32
- const value = extraQuery[key]
33
- parsedQuery[key] = Array.isArray(value) ? value.map(v => '' + v) : '' + value
34
- }
35
- return parsedQuery
36
- }
37
-
38
- function parseQuery (query: string): Dictionary<string> {
39
- const res = {}
40
-
41
- query = query.trim().replace(/^(\?|#|&)/, '')
42
-
43
- if (!query) {
44
- return res
45
- }
46
-
47
- query.split('&').forEach(param => {
48
- const parts = param.replace(/\+/g, ' ').split('=')
49
- const key = decode(parts.shift())
50
- const val = parts.length > 0
51
- ? decode(parts.join('='))
52
- : null
53
-
54
- if (res[key] === undefined) {
55
- res[key] = val
56
- } else if (Array.isArray(res[key])) {
57
- res[key].push(val)
58
- } else {
59
- res[key] = [res[key], val]
60
- }
61
- })
62
-
63
- return res
64
- }
65
-
66
- export function stringifyQuery (obj: Dictionary<string>): string {
67
- const res = obj ? Object.keys(obj).map(key => {
68
- const val = obj[key]
69
-
70
- if (val === undefined) {
71
- return ''
72
- }
73
-
74
- if (val === null) {
75
- return encode(key)
76
- }
77
-
78
- if (Array.isArray(val)) {
79
- const result = []
80
- val.forEach(val2 => {
81
- if (val2 === undefined) {
82
- return
83
- }
84
- if (val2 === null) {
85
- result.push(encode(key))
86
- } else {
87
- result.push(encode(key) + '=' + encode(val2))
88
- }
89
- })
90
- return result.join('&')
91
- }
92
-
93
- return encode(key) + '=' + encode(val)
94
- }).filter(x => x.length > 0).join('&') : null
95
- return res ? `?${res}` : ''
96
- }
1
+ /* @flow */
2
+
3
+ import { warn } from './warn'
4
+
5
+ const encodeReserveRE = /[!'()*]/g
6
+ const encodeReserveReplacer = c => '%' + c.charCodeAt(0).toString(16)
7
+ const commaRE = /%2C/g
8
+
9
+ // fixed encodeURIComponent which is more conformant to RFC3986:
10
+ // - escapes [!'()*]
11
+ // - preserve commas
12
+ const encode = str =>
13
+ encodeURIComponent(str)
14
+ .replace(encodeReserveRE, encodeReserveReplacer)
15
+ .replace(commaRE, ',')
16
+
17
+ export function decode (str: string) {
18
+ try {
19
+ return decodeURIComponent(str)
20
+ } catch (err) {
21
+ if (process.env.NODE_ENV !== 'production') {
22
+ warn(false, `Error decoding "${str}". Leaving it intact.`)
23
+ }
24
+ }
25
+ return str
26
+ }
27
+
28
+ export function resolveQuery (
29
+ query: ?string,
30
+ extraQuery: Dictionary<string> = {},
31
+ _parseQuery: ?Function
32
+ ): Dictionary<string> {
33
+ const parse = _parseQuery || parseQuery
34
+ let parsedQuery
35
+ try {
36
+ parsedQuery = parse(query || '')
37
+ } catch (e) {
38
+ process.env.NODE_ENV !== 'production' && warn(false, e.message)
39
+ parsedQuery = {}
40
+ }
41
+ for (const key in extraQuery) {
42
+ const value = extraQuery[key]
43
+ parsedQuery[key] = Array.isArray(value)
44
+ ? value.map(castQueryParamValue)
45
+ : castQueryParamValue(value)
46
+ }
47
+ return parsedQuery
48
+ }
49
+
50
+ const castQueryParamValue = value => (value == null || typeof value === 'object' ? value : String(value))
51
+
52
+ function parseQuery (query: string): Dictionary<string> {
53
+ const res = {}
54
+
55
+ query = query.trim().replace(/^(\?|#|&)/, '')
56
+
57
+ if (!query) {
58
+ return res
59
+ }
60
+
61
+ query.split('&').forEach(param => {
62
+ const parts = param.replace(/\+/g, ' ').split('=')
63
+ const key = decode(parts.shift())
64
+ const val = parts.length > 0 ? decode(parts.join('=')) : null
65
+
66
+ if (res[key] === undefined) {
67
+ res[key] = val
68
+ } else if (Array.isArray(res[key])) {
69
+ res[key].push(val)
70
+ } else {
71
+ res[key] = [res[key], val]
72
+ }
73
+ })
74
+
75
+ return res
76
+ }
77
+
78
+ export function stringifyQuery (obj: Dictionary<string>): string {
79
+ const res = obj
80
+ ? Object.keys(obj)
81
+ .map(key => {
82
+ const val = obj[key]
83
+
84
+ if (val === undefined) {
85
+ return ''
86
+ }
87
+
88
+ if (val === null) {
89
+ return encode(key)
90
+ }
91
+
92
+ if (Array.isArray(val)) {
93
+ const result = []
94
+ val.forEach(val2 => {
95
+ if (val2 === undefined) {
96
+ return
97
+ }
98
+ if (val2 === null) {
99
+ result.push(encode(key))
100
+ } else {
101
+ result.push(encode(key) + '=' + encode(val2))
102
+ }
103
+ })
104
+ return result.join('&')
105
+ }
106
+
107
+ return encode(key) + '=' + encode(val)
108
+ })
109
+ .filter(x => x.length > 0)
110
+ .join('&')
111
+ : null
112
+ return res ? `?${res}` : ''
113
+ }
@@ -1,109 +1,109 @@
1
- /* @flow */
2
-
3
- import { _Kdu } from '../install'
4
- import { warn } from './warn'
5
- import { isError } from '../util/errors'
6
-
7
- export function resolveAsyncComponents (matched: Array<RouteRecord>): Function {
8
- return (to, from, next) => {
9
- let hasAsync = false
10
- let pending = 0
11
- let error = null
12
-
13
- flatMapComponents(matched, (def, _, match, key) => {
14
- // if it's a function and doesn't have cid attached,
15
- // assume it's an async component resolve function.
16
- // we are not using Kdu's default async resolving mechanism because
17
- // we want to halt the navigation until the incoming component has been
18
- // resolved.
19
- if (typeof def === 'function' && def.cid === undefined) {
20
- hasAsync = true
21
- pending++
22
-
23
- const resolve = once(resolvedDef => {
24
- if (isESModule(resolvedDef)) {
25
- resolvedDef = resolvedDef.default
26
- }
27
- // save resolved on async factory in case it's used elsewhere
28
- def.resolved = typeof resolvedDef === 'function'
29
- ? resolvedDef
30
- : _Kdu.extend(resolvedDef)
31
- match.components[key] = resolvedDef
32
- pending--
33
- if (pending <= 0) {
34
- next()
35
- }
36
- })
37
-
38
- const reject = once(reason => {
39
- const msg = `Failed to resolve async component ${key}: ${reason}`
40
- process.env.NODE_ENV !== 'production' && warn(false, msg)
41
- if (!error) {
42
- error = isError(reason)
43
- ? reason
44
- : new Error(msg)
45
- next(error)
46
- }
47
- })
48
-
49
- let res
50
- try {
51
- res = def(resolve, reject)
52
- } catch (e) {
53
- reject(e)
54
- }
55
- if (res) {
56
- if (typeof res.then === 'function') {
57
- res.then(resolve, reject)
58
- } else {
59
- // new syntax in Kdu 2.3
60
- const comp = res.component
61
- if (comp && typeof comp.then === 'function') {
62
- comp.then(resolve, reject)
63
- }
64
- }
65
- }
66
- }
67
- })
68
-
69
- if (!hasAsync) next()
70
- }
71
- }
72
-
73
- export function flatMapComponents (
74
- matched: Array<RouteRecord>,
75
- fn: Function
76
- ): Array<?Function> {
77
- return flatten(matched.map(m => {
78
- return Object.keys(m.components).map(key => fn(
79
- m.components[key],
80
- m.instances[key],
81
- m, key
82
- ))
83
- }))
84
- }
85
-
86
- export function flatten (arr: Array<any>): Array<any> {
87
- return Array.prototype.concat.apply([], arr)
88
- }
89
-
90
- const hasSymbol =
91
- typeof Symbol === 'function' &&
92
- typeof Symbol.toStringTag === 'symbol'
93
-
94
- function isESModule (obj) {
95
- return obj.__esModule || (hasSymbol && obj[Symbol.toStringTag] === 'Module')
96
- }
97
-
98
- // in Webpack 2, require.ensure now also returns a Promise
99
- // so the resolve/reject functions may get called an extra time
100
- // if the user uses an arrow function shorthand that happens to
101
- // return that Promise.
102
- function once (fn) {
103
- let called = false
104
- return function (...args) {
105
- if (called) return
106
- called = true
107
- return fn.apply(this, args)
108
- }
109
- }
1
+ /* @flow */
2
+
3
+ import { _Kdu } from '../install'
4
+ import { warn } from './warn'
5
+ import { isError } from '../util/errors'
6
+
7
+ export function resolveAsyncComponents (matched: Array<RouteRecord>): Function {
8
+ return (to, from, next) => {
9
+ let hasAsync = false
10
+ let pending = 0
11
+ let error = null
12
+
13
+ flatMapComponents(matched, (def, _, match, key) => {
14
+ // if it's a function and doesn't have cid attached,
15
+ // assume it's an async component resolve function.
16
+ // we are not using Kdu's default async resolving mechanism because
17
+ // we want to halt the navigation until the incoming component has been
18
+ // resolved.
19
+ if (typeof def === 'function' && def.cid === undefined) {
20
+ hasAsync = true
21
+ pending++
22
+
23
+ const resolve = once(resolvedDef => {
24
+ if (isESModule(resolvedDef)) {
25
+ resolvedDef = resolvedDef.default
26
+ }
27
+ // save resolved on async factory in case it's used elsewhere
28
+ def.resolved = typeof resolvedDef === 'function'
29
+ ? resolvedDef
30
+ : _Kdu.extend(resolvedDef)
31
+ match.components[key] = resolvedDef
32
+ pending--
33
+ if (pending <= 0) {
34
+ next()
35
+ }
36
+ })
37
+
38
+ const reject = once(reason => {
39
+ const msg = `Failed to resolve async component ${key}: ${reason}`
40
+ process.env.NODE_ENV !== 'production' && warn(false, msg)
41
+ if (!error) {
42
+ error = isError(reason)
43
+ ? reason
44
+ : new Error(msg)
45
+ next(error)
46
+ }
47
+ })
48
+
49
+ let res
50
+ try {
51
+ res = def(resolve, reject)
52
+ } catch (e) {
53
+ reject(e)
54
+ }
55
+ if (res) {
56
+ if (typeof res.then === 'function') {
57
+ res.then(resolve, reject)
58
+ } else {
59
+ // new syntax in Kdu 2.3
60
+ const comp = res.component
61
+ if (comp && typeof comp.then === 'function') {
62
+ comp.then(resolve, reject)
63
+ }
64
+ }
65
+ }
66
+ }
67
+ })
68
+
69
+ if (!hasAsync) next()
70
+ }
71
+ }
72
+
73
+ export function flatMapComponents (
74
+ matched: Array<RouteRecord>,
75
+ fn: Function
76
+ ): Array<?Function> {
77
+ return flatten(matched.map(m => {
78
+ return Object.keys(m.components).map(key => fn(
79
+ m.components[key],
80
+ m.instances[key],
81
+ m, key
82
+ ))
83
+ }))
84
+ }
85
+
86
+ export function flatten (arr: Array<any>): Array<any> {
87
+ return Array.prototype.concat.apply([], arr)
88
+ }
89
+
90
+ const hasSymbol =
91
+ typeof Symbol === 'function' &&
92
+ typeof Symbol.toStringTag === 'symbol'
93
+
94
+ function isESModule (obj) {
95
+ return obj.__esModule || (hasSymbol && obj[Symbol.toStringTag] === 'Module')
96
+ }
97
+
98
+ // in Webpack 2, require.ensure now also returns a Promise
99
+ // so the resolve/reject functions may get called an extra time
100
+ // if the user uses an arrow function shorthand that happens to
101
+ // return that Promise.
102
+ function once (fn) {
103
+ let called = false
104
+ return function (...args) {
105
+ if (called) return
106
+ called = true
107
+ return fn.apply(this, args)
108
+ }
109
+ }