kdu-router 3.5.4 → 3.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -21
- package/README.md +11 -11
- package/dist/composables.js +253 -0
- package/dist/composables.mjs +244 -0
- package/dist/kdu-router.common.js +2668 -2665
- package/dist/kdu-router.esm.browser.js +2677 -2671
- package/dist/kdu-router.esm.browser.min.js +5 -5
- package/dist/kdu-router.esm.js +2672 -2666
- package/dist/kdu-router.js +2675 -2672
- package/dist/kdu-router.min.js +5 -5
- package/ketur/attributes.json +38 -38
- package/ketur/tags.json +20 -20
- package/package.json +115 -90
- package/src/components/link.js +224 -224
- package/src/components/view.js +155 -155
- package/src/composables/globals.js +34 -0
- package/src/composables/guards.js +68 -0
- package/src/composables/index.js +3 -0
- package/src/composables/useLink.js +113 -0
- package/src/composables/utils.js +11 -0
- package/src/create-matcher.js +226 -226
- package/src/create-route-map.js +220 -220
- package/src/entries/cjs.js +3 -0
- package/src/entries/esm.js +12 -0
- package/src/history/abstract.js +72 -72
- package/src/history/base.js +379 -379
- package/src/history/hash.js +152 -152
- package/src/history/html5.js +99 -99
- package/src/index.js +3 -293
- package/src/install.js +52 -52
- package/src/router.js +293 -0
- package/src/util/async.js +18 -18
- package/src/util/dom.js +3 -3
- package/src/util/errors.js +86 -86
- package/src/util/location.js +69 -69
- package/src/util/misc.js +6 -6
- package/src/util/params.js +37 -37
- package/src/util/path.js +74 -74
- package/src/util/push-state.js +46 -46
- package/src/util/query.js +113 -113
- package/src/util/resolve-components.js +109 -109
- package/src/util/route.js +151 -151
- package/src/util/scroll.js +175 -175
- package/src/util/state-key.js +22 -22
- package/src/util/warn.js +14 -14
- package/types/composables.d.ts +53 -0
- package/types/index.d.ts +25 -21
- package/types/kdu.d.ts +22 -22
- package/types/router.d.ts +564 -211
package/src/index.js
CHANGED
|
@@ -1,293 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
import { START } from './util/route'
|
|
5
|
-
import { assert, warn } from './util/warn'
|
|
6
|
-
import { inBrowser } from './util/dom'
|
|
7
|
-
import { cleanPath } from './util/path'
|
|
8
|
-
import { createMatcher } from './create-matcher'
|
|
9
|
-
import { normalizeLocation } from './util/location'
|
|
10
|
-
import { supportsPushState } from './util/push-state'
|
|
11
|
-
import { handleScroll } from './util/scroll'
|
|
12
|
-
|
|
13
|
-
import { HashHistory } from './history/hash'
|
|
14
|
-
import { HTML5History } from './history/html5'
|
|
15
|
-
import { AbstractHistory } from './history/abstract'
|
|
16
|
-
|
|
17
|
-
import type { Matcher } from './create-matcher'
|
|
18
|
-
|
|
19
|
-
import { isNavigationFailure, NavigationFailureType } from './util/errors'
|
|
20
|
-
|
|
21
|
-
export default class KduRouter {
|
|
22
|
-
static install: () => void
|
|
23
|
-
static version: string
|
|
24
|
-
static isNavigationFailure: Function
|
|
25
|
-
static NavigationFailureType: any
|
|
26
|
-
static START_LOCATION: Route
|
|
27
|
-
|
|
28
|
-
app: any
|
|
29
|
-
apps: Array<any>
|
|
30
|
-
ready: boolean
|
|
31
|
-
readyCbs: Array<Function>
|
|
32
|
-
options: RouterOptions
|
|
33
|
-
mode: string
|
|
34
|
-
history: HashHistory | HTML5History | AbstractHistory
|
|
35
|
-
matcher: Matcher
|
|
36
|
-
fallback: boolean
|
|
37
|
-
beforeHooks: Array<?NavigationGuard>
|
|
38
|
-
resolveHooks: Array<?NavigationGuard>
|
|
39
|
-
afterHooks: Array<?AfterNavigationHook>
|
|
40
|
-
|
|
41
|
-
constructor (options: RouterOptions = {}) {
|
|
42
|
-
if (process.env.NODE_ENV !== 'production') {
|
|
43
|
-
warn(this instanceof KduRouter, `Router must be called with the new operator.`)
|
|
44
|
-
}
|
|
45
|
-
this.app = null
|
|
46
|
-
this.apps = []
|
|
47
|
-
this.options = options
|
|
48
|
-
this.beforeHooks = []
|
|
49
|
-
this.resolveHooks = []
|
|
50
|
-
this.afterHooks = []
|
|
51
|
-
this.matcher = createMatcher(options.routes || [], this)
|
|
52
|
-
|
|
53
|
-
let mode = options.mode || 'hash'
|
|
54
|
-
this.fallback =
|
|
55
|
-
mode === 'history' && !supportsPushState && options.fallback !== false
|
|
56
|
-
if (this.fallback) {
|
|
57
|
-
mode = 'hash'
|
|
58
|
-
}
|
|
59
|
-
if (!inBrowser) {
|
|
60
|
-
mode = 'abstract'
|
|
61
|
-
}
|
|
62
|
-
this.mode = mode
|
|
63
|
-
|
|
64
|
-
switch (mode) {
|
|
65
|
-
case 'history':
|
|
66
|
-
this.history = new HTML5History(this, options.base)
|
|
67
|
-
break
|
|
68
|
-
case 'hash':
|
|
69
|
-
this.history = new HashHistory(this, options.base, this.fallback)
|
|
70
|
-
break
|
|
71
|
-
case 'abstract':
|
|
72
|
-
this.history = new AbstractHistory(this, options.base)
|
|
73
|
-
break
|
|
74
|
-
default:
|
|
75
|
-
if (process.env.NODE_ENV !== 'production') {
|
|
76
|
-
assert(false, `invalid mode: ${mode}`)
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
match (raw: RawLocation, current?: Route, redirectedFrom?: Location): Route {
|
|
82
|
-
return this.matcher.match(raw, current, redirectedFrom)
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
get currentRoute (): ?Route {
|
|
86
|
-
return this.history && this.history.current
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
init (app: any /* Kdu component instance */) {
|
|
90
|
-
process.env.NODE_ENV !== 'production' &&
|
|
91
|
-
assert(
|
|
92
|
-
install.installed,
|
|
93
|
-
`not installed. Make sure to call \`Kdu.use(KduRouter)\` ` +
|
|
94
|
-
`before creating root instance.`
|
|
95
|
-
)
|
|
96
|
-
|
|
97
|
-
this.apps.push(app)
|
|
98
|
-
|
|
99
|
-
// set up app destroyed handler
|
|
100
|
-
app.$once('hook:destroyed', () => {
|
|
101
|
-
// clean out app from this.apps array once destroyed
|
|
102
|
-
const index = this.apps.indexOf(app)
|
|
103
|
-
if (index > -1) this.apps.splice(index, 1)
|
|
104
|
-
// ensure we still have a main app or null if no apps
|
|
105
|
-
// we do not release the router so it can be reused
|
|
106
|
-
if (this.app === app) this.app = this.apps[0] || null
|
|
107
|
-
|
|
108
|
-
if (!this.app) this.history.teardown()
|
|
109
|
-
})
|
|
110
|
-
|
|
111
|
-
// main app previously initialized
|
|
112
|
-
// return as we don't need to set up new history listener
|
|
113
|
-
if (this.app) {
|
|
114
|
-
return
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
this.app = app
|
|
118
|
-
|
|
119
|
-
const history = this.history
|
|
120
|
-
|
|
121
|
-
if (history instanceof HTML5History || history instanceof HashHistory) {
|
|
122
|
-
const handleInitialScroll = routeOrError => {
|
|
123
|
-
const from = history.current
|
|
124
|
-
const expectScroll = this.options.scrollBehavior
|
|
125
|
-
const supportsScroll = supportsPushState && expectScroll
|
|
126
|
-
|
|
127
|
-
if (supportsScroll && 'fullPath' in routeOrError) {
|
|
128
|
-
handleScroll(this, routeOrError, from, false)
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
const setupListeners = routeOrError => {
|
|
132
|
-
history.setupListeners()
|
|
133
|
-
handleInitialScroll(routeOrError)
|
|
134
|
-
}
|
|
135
|
-
history.transitionTo(
|
|
136
|
-
history.getCurrentLocation(),
|
|
137
|
-
setupListeners,
|
|
138
|
-
setupListeners
|
|
139
|
-
)
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
history.listen(route => {
|
|
143
|
-
this.apps.forEach(app => {
|
|
144
|
-
app._route = route
|
|
145
|
-
})
|
|
146
|
-
})
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
beforeEach (fn: Function): Function {
|
|
150
|
-
return registerHook(this.beforeHooks, fn)
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
beforeResolve (fn: Function): Function {
|
|
154
|
-
return registerHook(this.resolveHooks, fn)
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
afterEach (fn: Function): Function {
|
|
158
|
-
return registerHook(this.afterHooks, fn)
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
onReady (cb: Function, errorCb?: Function) {
|
|
162
|
-
this.history.onReady(cb, errorCb)
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
onError (errorCb: Function) {
|
|
166
|
-
this.history.onError(errorCb)
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
push (location: RawLocation, onComplete?: Function, onAbort?: Function) {
|
|
170
|
-
// $flow-disable-line
|
|
171
|
-
if (!onComplete && !onAbort && typeof Promise !== 'undefined') {
|
|
172
|
-
return new Promise((resolve, reject) => {
|
|
173
|
-
this.history.push(location, resolve, reject)
|
|
174
|
-
})
|
|
175
|
-
} else {
|
|
176
|
-
this.history.push(location, onComplete, onAbort)
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
replace (location: RawLocation, onComplete?: Function, onAbort?: Function) {
|
|
181
|
-
// $flow-disable-line
|
|
182
|
-
if (!onComplete && !onAbort && typeof Promise !== 'undefined') {
|
|
183
|
-
return new Promise((resolve, reject) => {
|
|
184
|
-
this.history.replace(location, resolve, reject)
|
|
185
|
-
})
|
|
186
|
-
} else {
|
|
187
|
-
this.history.replace(location, onComplete, onAbort)
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
go (n: number) {
|
|
192
|
-
this.history.go(n)
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
back () {
|
|
196
|
-
this.go(-1)
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
forward () {
|
|
200
|
-
this.go(1)
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
getMatchedComponents (to?: RawLocation | Route): Array<any> {
|
|
204
|
-
const route: any = to
|
|
205
|
-
? to.matched
|
|
206
|
-
? to
|
|
207
|
-
: this.resolve(to).route
|
|
208
|
-
: this.currentRoute
|
|
209
|
-
if (!route) {
|
|
210
|
-
return []
|
|
211
|
-
}
|
|
212
|
-
return [].concat.apply(
|
|
213
|
-
[],
|
|
214
|
-
route.matched.map(m => {
|
|
215
|
-
return Object.keys(m.components).map(key => {
|
|
216
|
-
return m.components[key]
|
|
217
|
-
})
|
|
218
|
-
})
|
|
219
|
-
)
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
resolve (
|
|
223
|
-
to: RawLocation,
|
|
224
|
-
current?: Route,
|
|
225
|
-
append?: boolean
|
|
226
|
-
): {
|
|
227
|
-
location: Location,
|
|
228
|
-
route: Route,
|
|
229
|
-
href: string,
|
|
230
|
-
// for backwards compat
|
|
231
|
-
normalizedTo: Location,
|
|
232
|
-
resolved: Route
|
|
233
|
-
} {
|
|
234
|
-
current = current || this.history.current
|
|
235
|
-
const location = normalizeLocation(to, current, append, this)
|
|
236
|
-
const route = this.match(location, current)
|
|
237
|
-
const fullPath = route.redirectedFrom || route.fullPath
|
|
238
|
-
const base = this.history.base
|
|
239
|
-
const href = createHref(base, fullPath, this.mode)
|
|
240
|
-
return {
|
|
241
|
-
location,
|
|
242
|
-
route,
|
|
243
|
-
href,
|
|
244
|
-
// for backwards compat
|
|
245
|
-
normalizedTo: location,
|
|
246
|
-
resolved: route
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
getRoutes () {
|
|
251
|
-
return this.matcher.getRoutes()
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
addRoute (parentOrRoute: string | RouteConfig, route?: RouteConfig) {
|
|
255
|
-
this.matcher.addRoute(parentOrRoute, route)
|
|
256
|
-
if (this.history.current !== START) {
|
|
257
|
-
this.history.transitionTo(this.history.getCurrentLocation())
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
addRoutes (routes: Array<RouteConfig>) {
|
|
262
|
-
if (process.env.NODE_ENV !== 'production') {
|
|
263
|
-
warn(false, 'router.addRoutes() is deprecated and has been removed in Kdu Router 4. Use router.addRoute() instead.')
|
|
264
|
-
}
|
|
265
|
-
this.matcher.addRoutes(routes)
|
|
266
|
-
if (this.history.current !== START) {
|
|
267
|
-
this.history.transitionTo(this.history.getCurrentLocation())
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
function registerHook (list: Array<any>, fn: Function): Function {
|
|
273
|
-
list.push(fn)
|
|
274
|
-
return () => {
|
|
275
|
-
const i = list.indexOf(fn)
|
|
276
|
-
if (i > -1) list.splice(i, 1)
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
function createHref (base: string, fullPath: string, mode) {
|
|
281
|
-
var path = mode === 'hash' ? '#' + fullPath : fullPath
|
|
282
|
-
return base ? cleanPath(base + '/' + path) : path
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
KduRouter.install = install
|
|
286
|
-
KduRouter.version = '__VERSION__'
|
|
287
|
-
KduRouter.isNavigationFailure = isNavigationFailure
|
|
288
|
-
KduRouter.NavigationFailureType = NavigationFailureType
|
|
289
|
-
KduRouter.START_LOCATION = START
|
|
290
|
-
|
|
291
|
-
if (inBrowser && window.Kdu) {
|
|
292
|
-
window.Kdu.use(KduRouter)
|
|
293
|
-
}
|
|
1
|
+
import KduRouter from './entries/cjs'
|
|
2
|
+
|
|
3
|
+
export default KduRouter
|
package/src/install.js
CHANGED
|
@@ -1,52 +1,52 @@
|
|
|
1
|
-
import View from './components/view'
|
|
2
|
-
import Link from './components/link'
|
|
3
|
-
|
|
4
|
-
export let _Kdu
|
|
5
|
-
|
|
6
|
-
export function install (Kdu) {
|
|
7
|
-
if (install.installed && _Kdu === Kdu) return
|
|
8
|
-
install.installed = true
|
|
9
|
-
|
|
10
|
-
_Kdu = Kdu
|
|
11
|
-
|
|
12
|
-
const isDef = v => v !== undefined
|
|
13
|
-
|
|
14
|
-
const registerInstance = (vm, callVal) => {
|
|
15
|
-
let i = vm.$options._parentKnode
|
|
16
|
-
if (isDef(i) && isDef(i = i.data) && isDef(i = i.registerRouteInstance)) {
|
|
17
|
-
i(vm, callVal)
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
Kdu.mixin({
|
|
22
|
-
beforeCreate () {
|
|
23
|
-
if (isDef(this.$options.router)) {
|
|
24
|
-
this._routerRoot = this
|
|
25
|
-
this._router = this.$options.router
|
|
26
|
-
this._router.init(this)
|
|
27
|
-
Kdu.util.defineReactive(this, '_route', this._router.history.current)
|
|
28
|
-
} else {
|
|
29
|
-
this._routerRoot = (this.$parent && this.$parent._routerRoot) || this
|
|
30
|
-
}
|
|
31
|
-
registerInstance(this, this)
|
|
32
|
-
},
|
|
33
|
-
destroyed () {
|
|
34
|
-
registerInstance(this)
|
|
35
|
-
}
|
|
36
|
-
})
|
|
37
|
-
|
|
38
|
-
Object.defineProperty(Kdu.prototype, '$router', {
|
|
39
|
-
get () { return this._routerRoot._router }
|
|
40
|
-
})
|
|
41
|
-
|
|
42
|
-
Object.defineProperty(Kdu.prototype, '$route', {
|
|
43
|
-
get () { return this._routerRoot._route }
|
|
44
|
-
})
|
|
45
|
-
|
|
46
|
-
Kdu.component('RouterView', View)
|
|
47
|
-
Kdu.component('RouterLink', Link)
|
|
48
|
-
|
|
49
|
-
const strats = Kdu.config.optionMergeStrategies
|
|
50
|
-
// use the same hook merging strategy for route hooks
|
|
51
|
-
strats.beforeRouteEnter = strats.beforeRouteLeave = strats.beforeRouteUpdate = strats.created
|
|
52
|
-
}
|
|
1
|
+
import View from './components/view'
|
|
2
|
+
import Link from './components/link'
|
|
3
|
+
|
|
4
|
+
export let _Kdu
|
|
5
|
+
|
|
6
|
+
export function install (Kdu) {
|
|
7
|
+
if (install.installed && _Kdu === Kdu) return
|
|
8
|
+
install.installed = true
|
|
9
|
+
|
|
10
|
+
_Kdu = Kdu
|
|
11
|
+
|
|
12
|
+
const isDef = v => v !== undefined
|
|
13
|
+
|
|
14
|
+
const registerInstance = (vm, callVal) => {
|
|
15
|
+
let i = vm.$options._parentKnode
|
|
16
|
+
if (isDef(i) && isDef(i = i.data) && isDef(i = i.registerRouteInstance)) {
|
|
17
|
+
i(vm, callVal)
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
Kdu.mixin({
|
|
22
|
+
beforeCreate () {
|
|
23
|
+
if (isDef(this.$options.router)) {
|
|
24
|
+
this._routerRoot = this
|
|
25
|
+
this._router = this.$options.router
|
|
26
|
+
this._router.init(this)
|
|
27
|
+
Kdu.util.defineReactive(this, '_route', this._router.history.current)
|
|
28
|
+
} else {
|
|
29
|
+
this._routerRoot = (this.$parent && this.$parent._routerRoot) || this
|
|
30
|
+
}
|
|
31
|
+
registerInstance(this, this)
|
|
32
|
+
},
|
|
33
|
+
destroyed () {
|
|
34
|
+
registerInstance(this)
|
|
35
|
+
}
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
Object.defineProperty(Kdu.prototype, '$router', {
|
|
39
|
+
get () { return this._routerRoot._router }
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
Object.defineProperty(Kdu.prototype, '$route', {
|
|
43
|
+
get () { return this._routerRoot._route }
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
Kdu.component('RouterView', View)
|
|
47
|
+
Kdu.component('RouterLink', Link)
|
|
48
|
+
|
|
49
|
+
const strats = Kdu.config.optionMergeStrategies
|
|
50
|
+
// use the same hook merging strategy for route hooks
|
|
51
|
+
strats.beforeRouteEnter = strats.beforeRouteLeave = strats.beforeRouteUpdate = strats.created
|
|
52
|
+
}
|
package/src/router.js
ADDED
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
/* @flow */
|
|
2
|
+
|
|
3
|
+
import { install } from './install'
|
|
4
|
+
import { START } from './util/route'
|
|
5
|
+
import { assert, warn } from './util/warn'
|
|
6
|
+
import { inBrowser } from './util/dom'
|
|
7
|
+
import { cleanPath } from './util/path'
|
|
8
|
+
import { createMatcher } from './create-matcher'
|
|
9
|
+
import { normalizeLocation } from './util/location'
|
|
10
|
+
import { supportsPushState } from './util/push-state'
|
|
11
|
+
import { handleScroll } from './util/scroll'
|
|
12
|
+
import { isNavigationFailure, NavigationFailureType } from './util/errors'
|
|
13
|
+
|
|
14
|
+
import { HashHistory } from './history/hash'
|
|
15
|
+
import { HTML5History } from './history/html5'
|
|
16
|
+
import { AbstractHistory } from './history/abstract'
|
|
17
|
+
|
|
18
|
+
import type { Matcher } from './create-matcher'
|
|
19
|
+
|
|
20
|
+
export default class KduRouter {
|
|
21
|
+
static install: () => void
|
|
22
|
+
static version: string
|
|
23
|
+
static isNavigationFailure: Function
|
|
24
|
+
static NavigationFailureType: any
|
|
25
|
+
static START_LOCATION: Route
|
|
26
|
+
|
|
27
|
+
app: any
|
|
28
|
+
apps: Array<any>
|
|
29
|
+
ready: boolean
|
|
30
|
+
readyCbs: Array<Function>
|
|
31
|
+
options: RouterOptions
|
|
32
|
+
mode: string
|
|
33
|
+
history: HashHistory | HTML5History | AbstractHistory
|
|
34
|
+
matcher: Matcher
|
|
35
|
+
fallback: boolean
|
|
36
|
+
beforeHooks: Array<?NavigationGuard>
|
|
37
|
+
resolveHooks: Array<?NavigationGuard>
|
|
38
|
+
afterHooks: Array<?AfterNavigationHook>
|
|
39
|
+
|
|
40
|
+
constructor (options: RouterOptions = {}) {
|
|
41
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
42
|
+
warn(this instanceof KduRouter, `Router must be called with the new operator.`)
|
|
43
|
+
}
|
|
44
|
+
this.app = null
|
|
45
|
+
this.apps = []
|
|
46
|
+
this.options = options
|
|
47
|
+
this.beforeHooks = []
|
|
48
|
+
this.resolveHooks = []
|
|
49
|
+
this.afterHooks = []
|
|
50
|
+
this.matcher = createMatcher(options.routes || [], this)
|
|
51
|
+
|
|
52
|
+
let mode = options.mode || 'hash'
|
|
53
|
+
this.fallback =
|
|
54
|
+
mode === 'history' && !supportsPushState && options.fallback !== false
|
|
55
|
+
if (this.fallback) {
|
|
56
|
+
mode = 'hash'
|
|
57
|
+
}
|
|
58
|
+
if (!inBrowser) {
|
|
59
|
+
mode = 'abstract'
|
|
60
|
+
}
|
|
61
|
+
this.mode = mode
|
|
62
|
+
|
|
63
|
+
switch (mode) {
|
|
64
|
+
case 'history':
|
|
65
|
+
this.history = new HTML5History(this, options.base)
|
|
66
|
+
break
|
|
67
|
+
case 'hash':
|
|
68
|
+
this.history = new HashHistory(this, options.base, this.fallback)
|
|
69
|
+
break
|
|
70
|
+
case 'abstract':
|
|
71
|
+
this.history = new AbstractHistory(this, options.base)
|
|
72
|
+
break
|
|
73
|
+
default:
|
|
74
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
75
|
+
assert(false, `invalid mode: ${mode}`)
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
match (raw: RawLocation, current?: Route, redirectedFrom?: Location): Route {
|
|
81
|
+
return this.matcher.match(raw, current, redirectedFrom)
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
get currentRoute (): ?Route {
|
|
85
|
+
return this.history && this.history.current
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
init (app: any /* Kdu component instance */) {
|
|
89
|
+
process.env.NODE_ENV !== 'production' &&
|
|
90
|
+
assert(
|
|
91
|
+
install.installed,
|
|
92
|
+
`not installed. Make sure to call \`Kdu.use(KduRouter)\` ` +
|
|
93
|
+
`before creating root instance.`
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
this.apps.push(app)
|
|
97
|
+
|
|
98
|
+
// set up app destroyed handler
|
|
99
|
+
app.$once('hook:destroyed', () => {
|
|
100
|
+
// clean out app from this.apps array once destroyed
|
|
101
|
+
const index = this.apps.indexOf(app)
|
|
102
|
+
if (index > -1) this.apps.splice(index, 1)
|
|
103
|
+
// ensure we still have a main app or null if no apps
|
|
104
|
+
// we do not release the router so it can be reused
|
|
105
|
+
if (this.app === app) this.app = this.apps[0] || null
|
|
106
|
+
|
|
107
|
+
if (!this.app) this.history.teardown()
|
|
108
|
+
})
|
|
109
|
+
|
|
110
|
+
// main app previously initialized
|
|
111
|
+
// return as we don't need to set up new history listener
|
|
112
|
+
if (this.app) {
|
|
113
|
+
return
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
this.app = app
|
|
117
|
+
|
|
118
|
+
const history = this.history
|
|
119
|
+
|
|
120
|
+
if (history instanceof HTML5History || history instanceof HashHistory) {
|
|
121
|
+
const handleInitialScroll = routeOrError => {
|
|
122
|
+
const from = history.current
|
|
123
|
+
const expectScroll = this.options.scrollBehavior
|
|
124
|
+
const supportsScroll = supportsPushState && expectScroll
|
|
125
|
+
|
|
126
|
+
if (supportsScroll && 'fullPath' in routeOrError) {
|
|
127
|
+
handleScroll(this, routeOrError, from, false)
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
const setupListeners = routeOrError => {
|
|
131
|
+
history.setupListeners()
|
|
132
|
+
handleInitialScroll(routeOrError)
|
|
133
|
+
}
|
|
134
|
+
history.transitionTo(
|
|
135
|
+
history.getCurrentLocation(),
|
|
136
|
+
setupListeners,
|
|
137
|
+
setupListeners
|
|
138
|
+
)
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
history.listen(route => {
|
|
142
|
+
this.apps.forEach(app => {
|
|
143
|
+
app._route = route
|
|
144
|
+
})
|
|
145
|
+
})
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
beforeEach (fn: Function): Function {
|
|
149
|
+
return registerHook(this.beforeHooks, fn)
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
beforeResolve (fn: Function): Function {
|
|
153
|
+
return registerHook(this.resolveHooks, fn)
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
afterEach (fn: Function): Function {
|
|
157
|
+
return registerHook(this.afterHooks, fn)
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
onReady (cb: Function, errorCb?: Function) {
|
|
161
|
+
this.history.onReady(cb, errorCb)
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
onError (errorCb: Function) {
|
|
165
|
+
this.history.onError(errorCb)
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
push (location: RawLocation, onComplete?: Function, onAbort?: Function) {
|
|
169
|
+
// $flow-disable-line
|
|
170
|
+
if (!onComplete && !onAbort && typeof Promise !== 'undefined') {
|
|
171
|
+
return new Promise((resolve, reject) => {
|
|
172
|
+
this.history.push(location, resolve, reject)
|
|
173
|
+
})
|
|
174
|
+
} else {
|
|
175
|
+
this.history.push(location, onComplete, onAbort)
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
replace (location: RawLocation, onComplete?: Function, onAbort?: Function) {
|
|
180
|
+
// $flow-disable-line
|
|
181
|
+
if (!onComplete && !onAbort && typeof Promise !== 'undefined') {
|
|
182
|
+
return new Promise((resolve, reject) => {
|
|
183
|
+
this.history.replace(location, resolve, reject)
|
|
184
|
+
})
|
|
185
|
+
} else {
|
|
186
|
+
this.history.replace(location, onComplete, onAbort)
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
go (n: number) {
|
|
191
|
+
this.history.go(n)
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
back () {
|
|
195
|
+
this.go(-1)
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
forward () {
|
|
199
|
+
this.go(1)
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
getMatchedComponents (to?: RawLocation | Route): Array<any> {
|
|
203
|
+
const route: any = to
|
|
204
|
+
? to.matched
|
|
205
|
+
? to
|
|
206
|
+
: this.resolve(to).route
|
|
207
|
+
: this.currentRoute
|
|
208
|
+
if (!route) {
|
|
209
|
+
return []
|
|
210
|
+
}
|
|
211
|
+
return [].concat.apply(
|
|
212
|
+
[],
|
|
213
|
+
route.matched.map(m => {
|
|
214
|
+
return Object.keys(m.components).map(key => {
|
|
215
|
+
return m.components[key]
|
|
216
|
+
})
|
|
217
|
+
})
|
|
218
|
+
)
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
resolve (
|
|
222
|
+
to: RawLocation,
|
|
223
|
+
current?: Route,
|
|
224
|
+
append?: boolean
|
|
225
|
+
): {
|
|
226
|
+
location: Location,
|
|
227
|
+
route: Route,
|
|
228
|
+
href: string,
|
|
229
|
+
// for backwards compat
|
|
230
|
+
normalizedTo: Location,
|
|
231
|
+
resolved: Route
|
|
232
|
+
} {
|
|
233
|
+
current = current || this.history.current
|
|
234
|
+
const location = normalizeLocation(to, current, append, this)
|
|
235
|
+
const route = this.match(location, current)
|
|
236
|
+
const fullPath = route.redirectedFrom || route.fullPath
|
|
237
|
+
const base = this.history.base
|
|
238
|
+
const href = createHref(base, fullPath, this.mode)
|
|
239
|
+
return {
|
|
240
|
+
location,
|
|
241
|
+
route,
|
|
242
|
+
href,
|
|
243
|
+
// for backwards compat
|
|
244
|
+
normalizedTo: location,
|
|
245
|
+
resolved: route
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
getRoutes () {
|
|
250
|
+
return this.matcher.getRoutes()
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
addRoute (parentOrRoute: string | RouteConfig, route?: RouteConfig) {
|
|
254
|
+
this.matcher.addRoute(parentOrRoute, route)
|
|
255
|
+
if (this.history.current !== START) {
|
|
256
|
+
this.history.transitionTo(this.history.getCurrentLocation())
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
addRoutes (routes: Array<RouteConfig>) {
|
|
261
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
262
|
+
warn(false, 'router.addRoutes() is deprecated and has been removed in Kdu Router 4. Use router.addRoute() instead.')
|
|
263
|
+
}
|
|
264
|
+
this.matcher.addRoutes(routes)
|
|
265
|
+
if (this.history.current !== START) {
|
|
266
|
+
this.history.transitionTo(this.history.getCurrentLocation())
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
function registerHook (list: Array<any>, fn: Function): Function {
|
|
272
|
+
list.push(fn)
|
|
273
|
+
return () => {
|
|
274
|
+
const i = list.indexOf(fn)
|
|
275
|
+
if (i > -1) list.splice(i, 1)
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
function createHref (base: string, fullPath: string, mode) {
|
|
280
|
+
var path = mode === 'hash' ? '#' + fullPath : fullPath
|
|
281
|
+
return base ? cleanPath(base + '/' + path) : path
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
// We cannot remove this as it would be a breaking change
|
|
285
|
+
KduRouter.install = install
|
|
286
|
+
KduRouter.version = '__VERSION__'
|
|
287
|
+
KduRouter.isNavigationFailure = isNavigationFailure
|
|
288
|
+
KduRouter.NavigationFailureType = NavigationFailureType
|
|
289
|
+
KduRouter.START_LOCATION = START
|
|
290
|
+
|
|
291
|
+
if (inBrowser && window.Kdu) {
|
|
292
|
+
window.Kdu.use(KduRouter)
|
|
293
|
+
}
|