@@ -21,47 +21,62 @@ const regexpCompileCache: {
21
21
export function createMatcher ( routes : Array < RouteConfig > ) : Matcher {
22
22
const { pathMap, nameMap } = createRouteMap ( routes )
23
23
24
- function match ( raw : RawLocation , currentRoute ?: Route ) : Route {
24
+ function match (
25
+ raw : RawLocation ,
26
+ currentRoute ?: Route ,
27
+ redirectedFrom ?: Location
28
+ ) : Route {
25
29
const location = normalizeLocation ( raw , currentRoute )
26
30
const { name } = location
27
31
28
32
if ( name ) {
29
33
const record = nameMap [ name ]
30
34
if ( record ) {
31
35
location . path = fillParams ( record . path , location . params , `named route "${ name } "` )
32
- return createRouteContext ( record , location )
36
+ return createRouteContext ( record , location , redirectedFrom )
33
37
}
34
38
} else if ( location . path ) {
35
39
location . params = { }
36
40
for ( const path in pathMap ) {
37
41
if ( matchRoute ( path , location . params , location . path ) ) {
38
- return createRouteContext ( pathMap [ path ] , location )
42
+ return createRouteContext ( pathMap [ path ] , location , redirectedFrom )
39
43
}
40
44
}
41
45
}
42
46
// no match
43
47
return createRouteContext ( null , location )
44
48
}
45
49
46
- function createRouteContext ( record : ?RouteRecord , location : Location ) : Route {
50
+ function createRouteContext (
51
+ record : ?RouteRecord ,
52
+ location : Location ,
53
+ redirectedFrom ?: Location
54
+ ) : Route {
47
55
if ( record && record . redirect ) {
48
- return redirect ( record , location )
56
+ return redirect ( record , redirectedFrom || location )
49
57
}
50
58
if ( record && record . matchAs ) {
51
59
return alias ( record , location , record . matchAs )
52
60
}
53
- return Object . freeze ( {
61
+ const route : Route = {
54
62
name : location . name ,
55
63
path : location . path || '/' ,
56
64
hash : location . hash || '' ,
57
65
query : location . query || { } ,
58
66
params : location . params || { } ,
59
67
fullPath : getFullPath ( location ) ,
60
68
matched : record ? formatMatch ( record ) : [ ]
61
- } )
69
+ }
70
+ if ( redirectedFrom ) {
71
+ route . redirectedFrom = getFullPath ( redirectedFrom )
72
+ }
73
+ return Object . freeze ( route )
62
74
}
63
75
64
- function redirect ( record : RouteRecord , location : Location ) : Route {
76
+ function redirect (
77
+ record : RouteRecord ,
78
+ location : Location
79
+ ) : Route {
65
80
const { query, hash, params } = location
66
81
const { redirect } = record
67
82
const name = redirect && typeof redirect === 'object' && redirect . name
@@ -75,7 +90,7 @@ export function createMatcher (routes: Array<RouteConfig>): Matcher {
75
90
query,
76
91
hash,
77
92
params
78
- } )
93
+ } , undefined , location )
79
94
} else if ( typeof redirect === 'string' ) {
80
95
// 1. resolve relative redirect
81
96
const rawPath = resolveRecordPath ( redirect , record )
@@ -87,14 +102,18 @@ export function createMatcher (routes: Array<RouteConfig>): Matcher {
87
102
path,
88
103
query,
89
104
hash
90
- } )
105
+ } , undefined , location )
91
106
} else {
92
107
warn ( `invalid redirect option: ${ JSON . stringify ( redirect ) } ` )
93
108
return createRouteContext ( null , location )
94
109
}
95
110
}
96
111
97
- function alias ( record : RouteRecord , location : Location , matchAs : string ) : Route {
112
+ function alias (
113
+ record : RouteRecord ,
114
+ location : Location ,
115
+ matchAs : string
116
+ ) : Route {
98
117
const aliasedPath = fillParams ( matchAs , location . params , `aliased route with path "${ matchAs } "` )
99
118
const aliasedMatch = match ( {
100
119
_normalized : true ,
@@ -112,7 +131,11 @@ export function createMatcher (routes: Array<RouteConfig>): Matcher {
112
131
return match
113
132
}
114
133
115
- function matchRoute ( path : string , params : Object , pathname : string ) : boolean {
134
+ function matchRoute (
135
+ path : string ,
136
+ params : Object ,
137
+ pathname : string
138
+ ) : boolean {
116
139
let keys , regexp
117
140
const hit = regexpCache [ path ]
118
141
if ( hit ) {
@@ -140,16 +163,11 @@ function matchRoute (path: string, params: Object, pathname: string): boolean {
140
163
return true
141
164
}
142
165
143
- function formatMatch ( record : ?RouteRecord ) : Array < RouteRecord > {
144
- const res = [ ]
145
- while ( record ) {
146
- res . unshift ( record )
147
- record = record . parent
148
- }
149
- return res
150
- }
151
-
152
- function fillParams ( path : string , params : ?Object , routeMsg : string ) : string {
166
+ function fillParams (
167
+ path : string ,
168
+ params : ?Object ,
169
+ routeMsg : string
170
+ ) : string {
153
171
try {
154
172
const filler =
155
173
regexpCompileCache [ path ] ||
@@ -161,6 +179,15 @@ function fillParams (path: string, params: ?Object, routeMsg: string): string {
161
179
}
162
180
}
163
181
182
+ function formatMatch ( record : ?RouteRecord ) : Array < RouteRecord > {
183
+ const res = [ ]
184
+ while ( record ) {
185
+ res . unshift ( record )
186
+ record = record . parent
187
+ }
188
+ return res
189
+ }
190
+
164
191
function resolveRecordPath ( path : string , record : RouteRecord ) : string {
165
192
return resolvePath ( path , record . parent ? record . parent . path : '/' , true )
166
193
}
0 commit comments