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,69 +0,0 @@
1
- /* @flow */
2
-
3
- import type KduRouter from '../index'
4
- import { parsePath, resolvePath } from './path'
5
- import { resolveQuery } from './query'
6
- import { fillParams } from './params'
7
- import { warn } from './warn'
8
- import { extend } from './misc'
9
-
10
- export function normalizeLocation (
11
- raw: RawLocation,
12
- current: ?Route,
13
- append: ?boolean,
14
- router: ?KduRouter
15
- ): Location {
16
- let next: Location = typeof raw === 'string' ? { path: raw } : raw
17
- // named target
18
- if (next._normalized) {
19
- return next
20
- } else if (next.name) {
21
- next = extend({}, raw)
22
- const params = next.params
23
- if (params && typeof params === 'object') {
24
- next.params = extend({}, params)
25
- }
26
- return next
27
- }
28
-
29
- // relative params
30
- if (!next.path && next.params && current) {
31
- next = extend({}, next)
32
- next._normalized = true
33
- const params: any = extend(extend({}, current.params), next.params)
34
- if (current.name) {
35
- next.name = current.name
36
- next.params = params
37
- } else if (current.matched.length) {
38
- const rawPath = current.matched[current.matched.length - 1].path
39
- next.path = fillParams(rawPath, params, `path ${current.path}`)
40
- } else if (process.env.NODE_ENV !== 'production') {
41
- warn(false, `relative params navigation requires a current route.`)
42
- }
43
- return next
44
- }
45
-
46
- const parsedPath = parsePath(next.path || '')
47
- const basePath = (current && current.path) || '/'
48
- const path = parsedPath.path
49
- ? resolvePath(parsedPath.path, basePath, append || next.append)
50
- : basePath
51
-
52
- const query = resolveQuery(
53
- parsedPath.query,
54
- next.query,
55
- router && router.options.parseQuery
56
- )
57
-
58
- let hash = next.hash || parsedPath.hash
59
- if (hash && hash.charAt(0) !== '#') {
60
- hash = `#${hash}`
61
- }
62
-
63
- return {
64
- _normalized: true,
65
- path,
66
- query,
67
- hash
68
- }
69
- }
package/src/util/misc.js DELETED
@@ -1,6 +0,0 @@
1
- export function extend (a, b) {
2
- for (const key in b) {
3
- a[key] = b[key]
4
- }
5
- return a
6
- }
@@ -1,37 +0,0 @@
1
- /* @flow */
2
-
3
- import { warn } from './warn'
4
- import Regexp from 'path-to-regexp'
5
-
6
- // $flow-disable-line
7
- const regexpCompileCache: {
8
- [key: string]: Function
9
- } = Object.create(null)
10
-
11
- export function fillParams (
12
- path: string,
13
- params: ?Object,
14
- routeMsg: string
15
- ): string {
16
- params = params || {}
17
- try {
18
- const filler =
19
- regexpCompileCache[path] ||
20
- (regexpCompileCache[path] = Regexp.compile(path))
21
-
22
- // Fix #2505 resolving asterisk routes { name: 'not-found', params: { pathMatch: '/not-found' }}
23
- // and fix #3106 so that you can work with location descriptor object having params.pathMatch equal to empty string
24
- if (typeof params.pathMatch === 'string') params[0] = params.pathMatch
25
-
26
- return filler(params, { pretty: true })
27
- } catch (e) {
28
- if (process.env.NODE_ENV !== 'production') {
29
- // Fix #3072 no warn if `pathMatch` is string
30
- warn(typeof params.pathMatch === 'string', `missing param for ${routeMsg}: ${e.message}`)
31
- }
32
- return ''
33
- } finally {
34
- // delete the 0 if it was added
35
- delete params[0]
36
- }
37
- }
package/src/util/path.js DELETED
@@ -1,74 +0,0 @@
1
- /* @flow */
2
-
3
- export function resolvePath (
4
- relative: string,
5
- base: string,
6
- append?: boolean
7
- ): string {
8
- const firstChar = relative.charAt(0)
9
- if (firstChar === '/') {
10
- return relative
11
- }
12
-
13
- if (firstChar === '?' || firstChar === '#') {
14
- return base + relative
15
- }
16
-
17
- const stack = base.split('/')
18
-
19
- // remove trailing segment if:
20
- // - not appending
21
- // - appending to trailing slash (last segment is empty)
22
- if (!append || !stack[stack.length - 1]) {
23
- stack.pop()
24
- }
25
-
26
- // resolve relative path
27
- const segments = relative.replace(/^\//, '').split('/')
28
- for (let i = 0; i < segments.length; i++) {
29
- const segment = segments[i]
30
- if (segment === '..') {
31
- stack.pop()
32
- } else if (segment !== '.') {
33
- stack.push(segment)
34
- }
35
- }
36
-
37
- // ensure leading slash
38
- if (stack[0] !== '') {
39
- stack.unshift('')
40
- }
41
-
42
- return stack.join('/')
43
- }
44
-
45
- export function parsePath (path: string): {
46
- path: string;
47
- query: string;
48
- hash: string;
49
- } {
50
- let hash = ''
51
- let query = ''
52
-
53
- const hashIndex = path.indexOf('#')
54
- if (hashIndex >= 0) {
55
- hash = path.slice(hashIndex)
56
- path = path.slice(0, hashIndex)
57
- }
58
-
59
- const queryIndex = path.indexOf('?')
60
- if (queryIndex >= 0) {
61
- query = path.slice(queryIndex + 1)
62
- path = path.slice(0, queryIndex)
63
- }
64
-
65
- return {
66
- path,
67
- query,
68
- hash
69
- }
70
- }
71
-
72
- export function cleanPath (path: string): string {
73
- return path.replace(/\/(?:\s*\/)+/g, '/')
74
- }
@@ -1,46 +0,0 @@
1
- /* @flow */
2
-
3
- import { inBrowser } from './dom'
4
- import { saveScrollPosition } from './scroll'
5
- import { genStateKey, setStateKey, getStateKey } from './state-key'
6
- import { extend } from './misc'
7
-
8
- export const supportsPushState =
9
- inBrowser &&
10
- (function () {
11
- const ua = window.navigator.userAgent
12
-
13
- if (
14
- (ua.indexOf('Android 2.') !== -1 || ua.indexOf('Android 4.0') !== -1) &&
15
- ua.indexOf('Mobile Safari') !== -1 &&
16
- ua.indexOf('Chrome') === -1 &&
17
- ua.indexOf('Windows Phone') === -1
18
- ) {
19
- return false
20
- }
21
-
22
- return window.history && typeof window.history.pushState === 'function'
23
- })()
24
-
25
- export function pushState (url?: string, replace?: boolean) {
26
- saveScrollPosition()
27
- // try...catch the pushState call to get around Safari
28
- // DOM Exception 18 where it limits to 100 pushState calls
29
- const history = window.history
30
- try {
31
- if (replace) {
32
- // preserve existing history state as it could be overriden by the user
33
- const stateCopy = extend({}, history.state)
34
- stateCopy.key = getStateKey()
35
- history.replaceState(stateCopy, '', url)
36
- } else {
37
- history.pushState({ key: setStateKey(genStateKey()) }, '', url)
38
- }
39
- } catch (e) {
40
- window.location[replace ? 'replace' : 'assign'](url)
41
- }
42
- }
43
-
44
- export function replaceState (url?: string) {
45
- pushState(url, true)
46
- }
package/src/util/query.js DELETED
@@ -1,113 +0,0 @@
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 +0,0 @@
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
- }
package/src/util/route.js DELETED
@@ -1,151 +0,0 @@
1
- /* @flow */
2
-
3
- import type KduRouter from '../index'
4
- import { stringifyQuery } from './query'
5
-
6
- const trailingSlashRE = /\/?$/
7
-
8
- export function createRoute (
9
- record: ?RouteRecord,
10
- location: Location,
11
- redirectedFrom?: ?Location,
12
- router?: KduRouter
13
- ): Route {
14
- const stringifyQuery = router && router.options.stringifyQuery
15
-
16
- let query: any = location.query || {}
17
- try {
18
- query = clone(query)
19
- } catch (e) {}
20
-
21
- const route: Route = {
22
- name: location.name || (record && record.name),
23
- meta: (record && record.meta) || {},
24
- path: location.path || '/',
25
- hash: location.hash || '',
26
- query,
27
- params: location.params || {},
28
- fullPath: getFullPath(location, stringifyQuery),
29
- matched: record ? formatMatch(record) : []
30
- }
31
- if (redirectedFrom) {
32
- route.redirectedFrom = getFullPath(redirectedFrom, stringifyQuery)
33
- }
34
- return Object.freeze(route)
35
- }
36
-
37
- function clone (value) {
38
- if (Array.isArray(value)) {
39
- return value.map(clone)
40
- } else if (value && typeof value === 'object') {
41
- const res = {}
42
- for (const key in value) {
43
- res[key] = clone(value[key])
44
- }
45
- return res
46
- } else {
47
- return value
48
- }
49
- }
50
-
51
- // the starting route that represents the initial state
52
- export const START = createRoute(null, {
53
- path: '/'
54
- })
55
-
56
- function formatMatch (record: ?RouteRecord): Array<RouteRecord> {
57
- const res = []
58
- while (record) {
59
- res.unshift(record)
60
- record = record.parent
61
- }
62
- return res
63
- }
64
-
65
- function getFullPath (
66
- { path, query = {}, hash = '' },
67
- _stringifyQuery
68
- ): string {
69
- const stringify = _stringifyQuery || stringifyQuery
70
- return (path || '/') + stringify(query) + hash
71
- }
72
-
73
- export function isSameRoute (a: Route, b: ?Route, onlyPath: ?boolean): boolean {
74
- if (b === START) {
75
- return a === b
76
- } else if (!b) {
77
- return false
78
- } else if (a.path && b.path) {
79
- return a.path.replace(trailingSlashRE, '') === b.path.replace(trailingSlashRE, '') && (onlyPath ||
80
- a.hash === b.hash &&
81
- isObjectEqual(a.query, b.query))
82
- } else if (a.name && b.name) {
83
- return (
84
- a.name === b.name &&
85
- (onlyPath || (
86
- a.hash === b.hash &&
87
- isObjectEqual(a.query, b.query) &&
88
- isObjectEqual(a.params, b.params))
89
- )
90
- )
91
- } else {
92
- return false
93
- }
94
- }
95
-
96
- function isObjectEqual (a = {}, b = {}): boolean {
97
- // handle null value #1566
98
- if (!a || !b) return a === b
99
- const aKeys = Object.keys(a).sort()
100
- const bKeys = Object.keys(b).sort()
101
- if (aKeys.length !== bKeys.length) {
102
- return false
103
- }
104
- return aKeys.every((key, i) => {
105
- const aVal = a[key]
106
- const bKey = bKeys[i]
107
- if (bKey !== key) return false
108
- const bVal = b[key]
109
- // query values can be null and undefined
110
- if (aVal == null || bVal == null) return aVal === bVal
111
- // check nested equality
112
- if (typeof aVal === 'object' && typeof bVal === 'object') {
113
- return isObjectEqual(aVal, bVal)
114
- }
115
- return String(aVal) === String(bVal)
116
- })
117
- }
118
-
119
- export function isIncludedRoute (current: Route, target: Route): boolean {
120
- return (
121
- current.path.replace(trailingSlashRE, '/').indexOf(
122
- target.path.replace(trailingSlashRE, '/')
123
- ) === 0 &&
124
- (!target.hash || current.hash === target.hash) &&
125
- queryIncludes(current.query, target.query)
126
- )
127
- }
128
-
129
- function queryIncludes (current: Dictionary<string>, target: Dictionary<string>): boolean {
130
- for (const key in target) {
131
- if (!(key in current)) {
132
- return false
133
- }
134
- }
135
- return true
136
- }
137
-
138
- export function handleRouteEntered (route: Route) {
139
- for (let i = 0; i < route.matched.length; i++) {
140
- const record = route.matched[i]
141
- for (const name in record.instances) {
142
- const instance = record.instances[name]
143
- const cbs = record.enteredCbs[name]
144
- if (!instance || !cbs) continue
145
- delete record.enteredCbs[name]
146
- for (let i = 0; i < cbs.length; i++) {
147
- if (!instance._isBeingDestroyed) cbs[i](instance)
148
- }
149
- }
150
- }
151
- }