@@ -5,6 +5,7 @@ import { warn } from '../util/warn'
5
5
import { inBrowser } from '../util/dom'
6
6
import { runQueue } from '../util/async'
7
7
import { START , isSameRoute } from '../util/route'
8
+ import { _Vue } from '../install'
8
9
9
10
export class History {
10
11
router : VueRouter ;
@@ -147,53 +148,82 @@ function resolveQueue (
147
148
}
148
149
}
149
150
150
- function extractGuard ( def , key ) {
151
- if ( typeof def === 'function' && def . options ) {
152
- return def . options [ key ]
153
- } else if ( def ) {
154
- return def [ key ]
151
+ function extractGuard (
152
+ def : Object | Function ,
153
+ key : string
154
+ ) : NavigationGuard | Array < NavigationGuard > {
155
+ if ( typeof def !== 'function' ) {
156
+ // extend now so that global mixins are applied.
157
+ def = _Vue . extend ( def )
155
158
}
159
+ return def . options [ key ]
156
160
}
157
161
158
162
function extractLeaveGuards ( matched : Array < RouteRecord > ) : Array < ?Function > {
159
- return flatMapComponents ( matched , ( def , instance ) => {
163
+ return flatten ( flatMapComponents ( matched , ( def , instance ) => {
160
164
const guard = extractGuard ( def , 'beforeRouteLeave' )
161
165
if ( guard ) {
162
- return function routeLeaveGuard ( ) {
163
- return guard . apply ( instance , arguments )
164
- }
166
+ return Array . isArray ( guard )
167
+ ? guard . map ( guard => wrapLeaveGuard ( guard , instance ) )
168
+ : wrapLeaveGuard ( guard , instance )
165
169
}
166
- } ) . reverse ( )
170
+ } ) . reverse ( ) )
171
+ }
172
+
173
+ function wrapLeaveGuard (
174
+ guard : NavigationGuard ,
175
+ instance : _Vue
176
+ ) : NavigationGuard {
177
+ return function routeLeaveGuard ( ) {
178
+ return guard . apply ( instance , arguments )
179
+ }
167
180
}
168
181
169
182
function extractEnterGuards (
170
183
matched : Array < RouteRecord > ,
171
184
cbs : Array < Function > ,
172
185
isValid : ( ) = > boolean
173
186
) : Array < ?Function > {
174
- return flatMapComponents ( matched , ( def , _ , match , key ) => {
187
+ return flatten ( flatMapComponents ( matched , ( def , _ , match , key ) => {
175
188
const guard = extractGuard ( def , 'beforeRouteEnter' )
176
189
if ( guard ) {
177
- return function routeEnterGuard ( to , from , next ) {
178
- return guard ( to , from , cb => {
179
- next ( cb )
180
- if ( typeof cb === 'function' ) {
181
- cbs . push ( ( ) => {
182
- // #750
183
- // if a router-view is wrapped with an out-in transition,
184
- // the instance may not have been registered at this time.
185
- // we will need to poll for registration until current route
186
- // is no longer valid.
187
- poll ( cb , match . instances , key , isValid )
188
- } )
189
- }
190
+ return Array . isArray ( guard )
191
+ ? guard . map ( guard => wrapEnterGuard ( guard , cbs , match , key , isValid ) )
192
+ : wrapEnterGuard ( guard , cbs , match , key , isValid )
193
+ }
194
+ } ) )
195
+ }
196
+
197
+ function wrapEnterGuard (
198
+ guard : NavigationGuard ,
199
+ cbs : Array < Function > ,
200
+ match : RouteRecord ,
201
+ key : string ,
202
+ isValid : ( ) = > boolean
203
+ ) : NavigationGuard {
204
+ return function routeEnterGuard ( to , from , next ) {
205
+ return guard ( to , from , cb => {
206
+ next ( cb )
207
+ if ( typeof cb === 'function' ) {
208
+ cbs . push ( ( ) => {
209
+ // #750
210
+ // if a router-view is wrapped with an out-in transition,
211
+ // the instance may not have been registered at this time.
212
+ // we will need to poll for registration until current route
213
+ // is no longer valid.
214
+ poll ( cb , match . instances , key , isValid )
190
215
} )
191
216
}
192
- }
193
- } )
217
+ } )
218
+ }
194
219
}
195
220
196
- function poll ( cb , instances , key , isValid ) {
221
+ function poll (
222
+ cb : any , // somehow flow cannot infer this is a function
223
+ instances : Object ,
224
+ key : string ,
225
+ isValid : ( ) = > boolean
226
+ ) {
197
227
if ( instances [ key ] ) {
198
228
cb ( instances [ key ] )
199
229
} else if ( isValid ( ) ) {
@@ -235,11 +265,15 @@ function flatMapComponents (
235
265
matched : Array < RouteRecord > ,
236
266
fn : Function
237
267
) : Array < ?Function > {
238
- return Array . prototype . concat . apply ( [ ] , matched . map ( m => {
268
+ return flatten ( matched . map ( m => {
239
269
return Object . keys ( m . components ) . map ( key => fn (
240
270
m . components [ key ] ,
241
271
m . instances [ key ] ,
242
272
m , key
243
273
) )
244
274
} ) )
245
275
}
276
+
277
+ function flatten ( arr ) {
278
+ return Array . prototype . concat . apply ( [ ] , arr )
279
+ }
0 commit comments